IncludeCPP 2.4.2__tar.gz → 2.4.3__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.
- {includecpp-2.4.2 → includecpp-2.4.3}/IncludeCPP.egg-info/PKG-INFO +1 -1
- {includecpp-2.4.2 → includecpp-2.4.3}/PKG-INFO +1 -1
- {includecpp-2.4.2 → includecpp-2.4.3}/includecpp/__init__.py +1 -1
- {includecpp-2.4.2 → includecpp-2.4.3}/includecpp/cli/commands.py +80 -12
- {includecpp-2.4.2 → includecpp-2.4.3}/includecpp/core/build_manager.py +139 -21
- {includecpp-2.4.2 → includecpp-2.4.3}/includecpp/generator/parser.cpp +61 -3
- {includecpp-2.4.2 → includecpp-2.4.3}/includecpp/generator/parser.h +6 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/pyproject.toml +1 -1
- {includecpp-2.4.2 → includecpp-2.4.3}/setup.py +1 -1
- {includecpp-2.4.2 → includecpp-2.4.3}/IncludeCPP.egg-info/SOURCES.txt +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/IncludeCPP.egg-info/dependency_links.txt +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/IncludeCPP.egg-info/entry_points.txt +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/IncludeCPP.egg-info/requires.txt +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/IncludeCPP.egg-info/top_level.txt +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/LICENSE +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/MANIFEST.in +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/README.md +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/includecpp/__init__.pyi +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/includecpp/__main__.py +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/includecpp/cli/__init__.py +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/includecpp/cli/config_parser.py +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/includecpp/core/__init__.py +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/includecpp/core/cpp_api.py +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/includecpp/core/cpp_api.pyi +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/includecpp/core/error_formatter.py +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/includecpp/core/exceptions.py +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/includecpp/core/path_discovery.py +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/includecpp/generator/__init__.py +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/includecpp/generator/type_resolver.cpp +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/includecpp/generator/type_resolver.h +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/includecpp/templates/cpp.proj.template +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/requirements.txt +0 -0
- {includecpp-2.4.2 → includecpp-2.4.3}/setup.cfg +0 -0
|
@@ -1393,10 +1393,58 @@ def plugin(plugin_name, files, private):
|
|
|
1393
1393
|
return class_body[public_start:public_start + next_access.start()]
|
|
1394
1394
|
return class_body[public_start:]
|
|
1395
1395
|
|
|
1396
|
+
def extract_param_types(params_str):
|
|
1397
|
+
"""Extract parameter types from a parameter string like 'double x, double y'."""
|
|
1398
|
+
if not params_str or params_str.strip() == '':
|
|
1399
|
+
return []
|
|
1400
|
+
|
|
1401
|
+
types = []
|
|
1402
|
+
# Split by comma, but be careful with template types like std::vector<int, alloc>
|
|
1403
|
+
depth = 0
|
|
1404
|
+
current = ''
|
|
1405
|
+
for char in params_str:
|
|
1406
|
+
if char in '<(':
|
|
1407
|
+
depth += 1
|
|
1408
|
+
current += char
|
|
1409
|
+
elif char in '>)':
|
|
1410
|
+
depth -= 1
|
|
1411
|
+
current += char
|
|
1412
|
+
elif char == ',' and depth == 0:
|
|
1413
|
+
types.append(current.strip())
|
|
1414
|
+
current = ''
|
|
1415
|
+
else:
|
|
1416
|
+
current += char
|
|
1417
|
+
if current.strip():
|
|
1418
|
+
types.append(current.strip())
|
|
1419
|
+
|
|
1420
|
+
# Extract just the type from each parameter (remove variable name)
|
|
1421
|
+
result = []
|
|
1422
|
+
for param in types:
|
|
1423
|
+
param = param.strip()
|
|
1424
|
+
if not param:
|
|
1425
|
+
continue
|
|
1426
|
+
# Remove default value if present
|
|
1427
|
+
if '=' in param:
|
|
1428
|
+
param = param.split('=')[0].strip()
|
|
1429
|
+
# Find the type: everything before the last word (variable name)
|
|
1430
|
+
# Handle cases like "const std::string& name" -> "const std::string&"
|
|
1431
|
+
parts = param.rsplit(None, 1)
|
|
1432
|
+
if len(parts) == 1:
|
|
1433
|
+
# Just a type, no name (e.g., in declaration "void foo(int)")
|
|
1434
|
+
result.append(parts[0])
|
|
1435
|
+
else:
|
|
1436
|
+
# Check if last part is a pointer/reference suffix attached to type
|
|
1437
|
+
type_part = parts[0]
|
|
1438
|
+
# Handle cases where * or & is attached to variable name
|
|
1439
|
+
if parts[1].startswith('*') or parts[1].startswith('&'):
|
|
1440
|
+
type_part = parts[0] + parts[1][0]
|
|
1441
|
+
result.append(type_part)
|
|
1442
|
+
return result
|
|
1443
|
+
|
|
1396
1444
|
def extract_methods(public_section, class_name):
|
|
1397
1445
|
"""Extract method names from public section, handling inline bodies."""
|
|
1398
1446
|
methods = set()
|
|
1399
|
-
|
|
1447
|
+
constructor_signatures = [] # v2.4.3: List of (param_types) tuples
|
|
1400
1448
|
|
|
1401
1449
|
# Method pattern that handles return types, const, and inline bodies
|
|
1402
1450
|
# Match: [modifiers] return_type method_name(params) [const] [{ body } | ;]
|
|
@@ -1418,8 +1466,7 @@ def plugin(plugin_name, files, private):
|
|
|
1418
1466
|
|
|
1419
1467
|
# Skip if method name is the class name (it's a constructor)
|
|
1420
1468
|
if method_name == class_name:
|
|
1421
|
-
|
|
1422
|
-
continue
|
|
1469
|
+
continue # Will be handled by dedicated constructor pattern
|
|
1423
1470
|
|
|
1424
1471
|
# Skip destructors
|
|
1425
1472
|
if method_name.startswith('~'):
|
|
@@ -1431,12 +1478,17 @@ def plugin(plugin_name, files, private):
|
|
|
1431
1478
|
|
|
1432
1479
|
methods.add(method_name)
|
|
1433
1480
|
|
|
1434
|
-
#
|
|
1435
|
-
constructor_pattern =
|
|
1436
|
-
|
|
1437
|
-
|
|
1481
|
+
# v2.4.3: Extract constructor signatures with parameter types
|
|
1482
|
+
constructor_pattern = re.compile(
|
|
1483
|
+
rf'(?:explicit\s+)?{re.escape(class_name)}\s*\(([^)]*)\)',
|
|
1484
|
+
re.MULTILINE
|
|
1485
|
+
)
|
|
1486
|
+
for match in constructor_pattern.finditer(public_section):
|
|
1487
|
+
params_str = match.group(1).strip()
|
|
1488
|
+
param_types = extract_param_types(params_str)
|
|
1489
|
+
constructor_signatures.append(tuple(param_types))
|
|
1438
1490
|
|
|
1439
|
-
return methods,
|
|
1491
|
+
return methods, constructor_signatures
|
|
1440
1492
|
|
|
1441
1493
|
all_files = cpp_files + h_files
|
|
1442
1494
|
|
|
@@ -1470,12 +1522,17 @@ def plugin(plugin_name, files, private):
|
|
|
1470
1522
|
public_section = extract_public_section(class_body, is_struct)
|
|
1471
1523
|
|
|
1472
1524
|
if class_name not in classes:
|
|
1473
|
-
classes[class_name] = {'methods': set(), 'constructors':
|
|
1525
|
+
classes[class_name] = {'methods': set(), 'constructors': []}
|
|
1474
1526
|
|
|
1475
1527
|
# Extract methods from public section
|
|
1476
|
-
methods,
|
|
1528
|
+
methods, constructor_sigs = extract_methods(public_section, class_name)
|
|
1477
1529
|
classes[class_name]['methods'].update(methods)
|
|
1478
|
-
|
|
1530
|
+
# v2.4.3: Merge constructor signatures (avoid duplicates)
|
|
1531
|
+
existing_ctors = set(classes[class_name]['constructors'])
|
|
1532
|
+
for sig in constructor_sigs:
|
|
1533
|
+
if sig not in existing_ctors:
|
|
1534
|
+
classes[class_name]['constructors'].append(sig)
|
|
1535
|
+
existing_ctors.add(sig)
|
|
1479
1536
|
|
|
1480
1537
|
# Find free functions (not inside class bodies)
|
|
1481
1538
|
# First, remove all class bodies from content to avoid matching class methods
|
|
@@ -1524,7 +1581,18 @@ def plugin(plugin_name, files, private):
|
|
|
1524
1581
|
cls_info = classes[cls_name]
|
|
1525
1582
|
f.write(f' {plugin_name} CLASS({cls_name}) {{\n')
|
|
1526
1583
|
|
|
1527
|
-
|
|
1584
|
+
# v2.4.3: Write all constructor overloads with parameter types
|
|
1585
|
+
if cls_info['constructors']:
|
|
1586
|
+
for ctor_params in cls_info['constructors']:
|
|
1587
|
+
if ctor_params:
|
|
1588
|
+
# Parametrized constructor
|
|
1589
|
+
params_str = ', '.join(ctor_params)
|
|
1590
|
+
f.write(f' CONSTRUCTOR({params_str})\n')
|
|
1591
|
+
else:
|
|
1592
|
+
# Default constructor
|
|
1593
|
+
f.write(f' CONSTRUCTOR()\n')
|
|
1594
|
+
else:
|
|
1595
|
+
# No constructors found, add default
|
|
1528
1596
|
f.write(f' CONSTRUCTOR()\n')
|
|
1529
1597
|
|
|
1530
1598
|
for method in sorted(cls_info['methods']):
|
|
@@ -579,10 +579,46 @@ endif()
|
|
|
579
579
|
else:
|
|
580
580
|
f.write(f' """C++ class: {class_name_inner}"""\n\n')
|
|
581
581
|
|
|
582
|
-
# Constructor
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
582
|
+
# v2.4.3: Constructor overloads with parameter types
|
|
583
|
+
constructors = cls.get('constructors', [])
|
|
584
|
+
if constructors and len(constructors) > 1:
|
|
585
|
+
# Multiple constructors - use @overload
|
|
586
|
+
for ctor in constructors:
|
|
587
|
+
param_types = ctor.get('params', [])
|
|
588
|
+
f.write(' @overload\n')
|
|
589
|
+
if param_types:
|
|
590
|
+
param_list = ['self']
|
|
591
|
+
for i, ptype in enumerate(param_types):
|
|
592
|
+
py_type = self._cpp_to_python_type(ptype)
|
|
593
|
+
param_list.append(f'arg{i}: {py_type}')
|
|
594
|
+
params_str = ', '.join(param_list)
|
|
595
|
+
f.write(f' def __init__({params_str}) -> None: ...\n')
|
|
596
|
+
else:
|
|
597
|
+
f.write(f' def __init__(self) -> None: ...\n')
|
|
598
|
+
f.write('\n')
|
|
599
|
+
# Actual implementation signature
|
|
600
|
+
f.write(' def __init__(self, *args: Any, **kwargs: Any) -> None:\n')
|
|
601
|
+
f.write(f' """Initialize {class_name_inner} instance"""\n')
|
|
602
|
+
f.write(' ...\n\n')
|
|
603
|
+
elif constructors and len(constructors) == 1:
|
|
604
|
+
# Single constructor
|
|
605
|
+
param_types = constructors[0].get('params', [])
|
|
606
|
+
if param_types:
|
|
607
|
+
param_list = ['self']
|
|
608
|
+
for i, ptype in enumerate(param_types):
|
|
609
|
+
py_type = self._cpp_to_python_type(ptype)
|
|
610
|
+
param_list.append(f'arg{i}: {py_type}')
|
|
611
|
+
params_str = ', '.join(param_list)
|
|
612
|
+
f.write(f' def __init__({params_str}) -> None:\n')
|
|
613
|
+
else:
|
|
614
|
+
f.write(f' def __init__(self) -> None:\n')
|
|
615
|
+
f.write(f' """Initialize {class_name_inner} instance"""\n')
|
|
616
|
+
f.write(' ...\n\n')
|
|
617
|
+
else:
|
|
618
|
+
# Fallback - generic constructor
|
|
619
|
+
f.write(' def __init__(self, *args: Any, **kwargs: Any) -> None:\n')
|
|
620
|
+
f.write(f' """Initialize {class_name_inner} instance"""\n')
|
|
621
|
+
f.write(' ...\n\n')
|
|
586
622
|
|
|
587
623
|
# Generate methods
|
|
588
624
|
methods = cls.get('methods', [])
|
|
@@ -645,6 +681,52 @@ endif()
|
|
|
645
681
|
|
|
646
682
|
f.write('\n\n')
|
|
647
683
|
|
|
684
|
+
# v2.4.3: Generate CppApi class with overloaded include() methods
|
|
685
|
+
# This is the KEY to making VSCode autocomplete work for module.Class
|
|
686
|
+
f.write('# CppApi with typed include() overloads for each module\n')
|
|
687
|
+
f.write('class CppApi:\n')
|
|
688
|
+
f.write(' """C++ API Manager with typed module loading.\n\n')
|
|
689
|
+
f.write(' The include() method returns a module wrapper with full type hints\n')
|
|
690
|
+
f.write(' for VSCode/PyCharm autocomplete support.\n')
|
|
691
|
+
f.write(' """\n\n')
|
|
692
|
+
|
|
693
|
+
f.write(' def __init__(self, project_root: Optional[str] = None, auto_update: bool = True) -> None:\n')
|
|
694
|
+
f.write(' """Initialize CppApi.\n\n')
|
|
695
|
+
f.write(' Args:\n')
|
|
696
|
+
f.write(' project_root: Path to project root (default: auto-detect)\n')
|
|
697
|
+
f.write(' auto_update: Whether to auto-rebuild on source changes\n')
|
|
698
|
+
f.write(' """\n')
|
|
699
|
+
f.write(' ...\n\n')
|
|
700
|
+
|
|
701
|
+
# Generate overloaded include() methods for each module
|
|
702
|
+
for module_name, _ in modules.items():
|
|
703
|
+
wrapper_class = f"{module_name.capitalize()}ModuleWrapper"
|
|
704
|
+
f.write(' @overload\n')
|
|
705
|
+
f.write(f' def include(self, module_name: str = "{module_name}", auto_update: Optional[bool] = None) -> {wrapper_class}: ...\n\n')
|
|
706
|
+
|
|
707
|
+
# Fallback overload for unknown modules
|
|
708
|
+
f.write(' @overload\n')
|
|
709
|
+
f.write(' def include(self, module_name: str, auto_update: Optional[bool] = None) -> Any: ...\n\n')
|
|
710
|
+
|
|
711
|
+
# Actual implementation signature
|
|
712
|
+
f.write(' def include(self, module_name: str, auto_update: Optional[bool] = None) -> Any:\n')
|
|
713
|
+
f.write(' """Load a C++ module.\n\n')
|
|
714
|
+
f.write(' Args:\n')
|
|
715
|
+
f.write(' module_name: Name of the module to load\n')
|
|
716
|
+
f.write(' auto_update: Override auto-update setting for this module\n\n')
|
|
717
|
+
f.write(' Returns:\n')
|
|
718
|
+
f.write(' ModuleWrapper with access to C++ classes, functions, and structs\n')
|
|
719
|
+
f.write(' """\n')
|
|
720
|
+
f.write(' ...\n\n')
|
|
721
|
+
|
|
722
|
+
f.write(' def rebuild(self, verbose: bool = False) -> bool:\n')
|
|
723
|
+
f.write(' """Rebuild all C++ modules."""\n')
|
|
724
|
+
f.write(' ...\n\n')
|
|
725
|
+
|
|
726
|
+
f.write(' def list_modules(self) -> List[str]:\n')
|
|
727
|
+
f.write(' """List available modules."""\n')
|
|
728
|
+
f.write(' ...\n')
|
|
729
|
+
|
|
648
730
|
if verbose:
|
|
649
731
|
print(f"Generated VSCode IntelliSense stubs: {pyi_file}")
|
|
650
732
|
|
|
@@ -728,25 +810,61 @@ endif()
|
|
|
728
810
|
else:
|
|
729
811
|
f.write(f' """C++ class: {class_name}"""\n\n')
|
|
730
812
|
|
|
731
|
-
# Constructor with
|
|
732
|
-
|
|
733
|
-
if
|
|
734
|
-
|
|
735
|
-
for
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
813
|
+
# v2.4.3: Constructor overloads with parameter types
|
|
814
|
+
constructors = cls.get('constructors', [])
|
|
815
|
+
if constructors and len(constructors) > 1:
|
|
816
|
+
# Multiple constructors - use @overload
|
|
817
|
+
for ctor in constructors:
|
|
818
|
+
param_types = ctor.get('params', [])
|
|
819
|
+
f.write(' @overload\n')
|
|
820
|
+
if param_types:
|
|
821
|
+
param_list = ['self']
|
|
822
|
+
for i, ptype in enumerate(param_types):
|
|
823
|
+
py_type = self._cpp_to_python_type(ptype)
|
|
824
|
+
param_list.append(f'arg{i}: {py_type}')
|
|
825
|
+
params_str = ', '.join(param_list)
|
|
826
|
+
f.write(f' def __init__({params_str}) -> None: ...\n')
|
|
742
827
|
else:
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
else:
|
|
828
|
+
f.write(f' def __init__(self) -> None: ...\n')
|
|
829
|
+
f.write('\n')
|
|
830
|
+
# Actual implementation signature
|
|
747
831
|
f.write(f' def __init__(self, *args: Any, **kwargs: Any) -> None:\n')
|
|
748
|
-
|
|
749
|
-
|
|
832
|
+
f.write(f' """Initialize {class_name} instance."""\n')
|
|
833
|
+
f.write(' ...\n\n')
|
|
834
|
+
elif constructors and len(constructors) == 1:
|
|
835
|
+
# Single constructor
|
|
836
|
+
param_types = constructors[0].get('params', [])
|
|
837
|
+
if param_types:
|
|
838
|
+
param_list = ['self']
|
|
839
|
+
for i, ptype in enumerate(param_types):
|
|
840
|
+
py_type = self._cpp_to_python_type(ptype)
|
|
841
|
+
param_list.append(f'arg{i}: {py_type}')
|
|
842
|
+
params_str = ', '.join(param_list)
|
|
843
|
+
f.write(f' def __init__({params_str}) -> None:\n')
|
|
844
|
+
else:
|
|
845
|
+
f.write(f' def __init__(self) -> None:\n')
|
|
846
|
+
f.write(f' """Initialize {class_name} instance."""\n')
|
|
847
|
+
f.write(' ...\n\n')
|
|
848
|
+
else:
|
|
849
|
+
# Fallback: legacy format or no constructor info
|
|
850
|
+
constructor_params = cls.get('constructor_params', [])
|
|
851
|
+
if constructor_params:
|
|
852
|
+
param_list = ['self']
|
|
853
|
+
for param in constructor_params:
|
|
854
|
+
param_name = param.get('name', 'arg')
|
|
855
|
+
param_type = self._cpp_to_python_type(param.get('type', 'Any'))
|
|
856
|
+
param_default = param.get('default', None)
|
|
857
|
+
if param_default:
|
|
858
|
+
py_default = self._convert_cpp_default(param_default, param_type)
|
|
859
|
+
param_list.append(f'{param_name}: {param_type} = {py_default}')
|
|
860
|
+
else:
|
|
861
|
+
param_list.append(f'{param_name}: {param_type}')
|
|
862
|
+
params_str = ', '.join(param_list)
|
|
863
|
+
f.write(f' def __init__({params_str}) -> None:\n')
|
|
864
|
+
else:
|
|
865
|
+
f.write(f' def __init__(self, *args: Any, **kwargs: Any) -> None:\n')
|
|
866
|
+
f.write(f' """Initialize {class_name} instance."""\n')
|
|
867
|
+
f.write(' ...\n\n')
|
|
750
868
|
|
|
751
869
|
# Methods
|
|
752
870
|
methods = cls.get('methods', [])
|
|
@@ -395,7 +395,26 @@ ModuleDescriptor API::parse_cp_file(const std::string& filepath) {
|
|
|
395
395
|
std::string mtrim = trim(mline);
|
|
396
396
|
if (mtrim.empty()) continue;
|
|
397
397
|
|
|
398
|
-
|
|
398
|
+
// v2.4.3: Parse CONSTRUCTOR(type1, type2, ...) for parametrized constructors
|
|
399
|
+
if (mtrim.find("CONSTRUCTOR") != std::string::npos) {
|
|
400
|
+
size_t c_start = mtrim.find('(');
|
|
401
|
+
size_t c_end = mtrim.rfind(')');
|
|
402
|
+
if (c_start != std::string::npos && c_end != std::string::npos) {
|
|
403
|
+
std::string params_str = mtrim.substr(c_start + 1, c_end - c_start - 1);
|
|
404
|
+
ConstructorInfo ctor;
|
|
405
|
+
if (!params_str.empty()) {
|
|
406
|
+
auto params = split(params_str, ',');
|
|
407
|
+
for (auto& p : params) {
|
|
408
|
+
std::string param_type = trim(p);
|
|
409
|
+
if (!param_type.empty()) {
|
|
410
|
+
ctor.param_types.push_back(param_type);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
cb.constructors.push_back(ctor);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
else if (mtrim.find("METHOD") != std::string::npos) {
|
|
399
418
|
size_t m_start = mtrim.find('(');
|
|
400
419
|
size_t m_end = mtrim.find(')');
|
|
401
420
|
if (m_start != std::string::npos && m_end != std::string::npos) {
|
|
@@ -594,7 +613,25 @@ std::string API::generate_class_bindings(const ClassBinding& cls, const ModuleDe
|
|
|
594
613
|
|
|
595
614
|
code << " py::class_<" << cls.class_name << ">("
|
|
596
615
|
<< mod.module_name << "_module, \"" << cls.class_name << "\")\n";
|
|
597
|
-
|
|
616
|
+
|
|
617
|
+
// v2.4.3: Generate all constructor overloads from CONSTRUCTOR() entries
|
|
618
|
+
if (cls.constructors.empty()) {
|
|
619
|
+
// Backward compatibility: default constructor if none specified
|
|
620
|
+
code << " .def(py::init<>())";
|
|
621
|
+
} else {
|
|
622
|
+
bool first = true;
|
|
623
|
+
for (const auto& ctor : cls.constructors) {
|
|
624
|
+
if (!first) code << "\n";
|
|
625
|
+
first = false;
|
|
626
|
+
|
|
627
|
+
code << " .def(py::init<";
|
|
628
|
+
for (size_t i = 0; i < ctor.param_types.size(); ++i) {
|
|
629
|
+
if (i > 0) code << ", ";
|
|
630
|
+
code << ctor.param_types[i];
|
|
631
|
+
}
|
|
632
|
+
code << ">())";
|
|
633
|
+
}
|
|
634
|
+
}
|
|
598
635
|
|
|
599
636
|
// Bind Initialize static method (factory method)
|
|
600
637
|
code << "\n .def_static(\"Initialize\", []() { return " << cls.class_name << "(); })";
|
|
@@ -1141,7 +1178,7 @@ std::string API::generate_registry_json(const std::vector<ModuleDescriptor>& mod
|
|
|
1141
1178
|
}
|
|
1142
1179
|
json << " ],\n";
|
|
1143
1180
|
|
|
1144
|
-
// Add classes with methods and documentation
|
|
1181
|
+
// Add classes with methods, constructors, and documentation
|
|
1145
1182
|
json << " \"classes\": [\n";
|
|
1146
1183
|
for (size_t j = 0; j < mod.classes.size(); ++j) {
|
|
1147
1184
|
const auto& cls = mod.classes[j];
|
|
@@ -1150,6 +1187,27 @@ std::string API::generate_registry_json(const std::vector<ModuleDescriptor>& mod
|
|
|
1150
1187
|
if (!cls.documentation.empty()) {
|
|
1151
1188
|
json << ",\n \"doc\": \"" << replace_all(cls.documentation, "\"", "\\\"") << "\"";
|
|
1152
1189
|
}
|
|
1190
|
+
|
|
1191
|
+
// v2.4.3: Add constructor signatures
|
|
1192
|
+
json << ",\n \"constructors\": [\n";
|
|
1193
|
+
if (cls.constructors.empty()) {
|
|
1194
|
+
// Default constructor
|
|
1195
|
+
json << " {\"params\": []}\n";
|
|
1196
|
+
} else {
|
|
1197
|
+
for (size_t k = 0; k < cls.constructors.size(); ++k) {
|
|
1198
|
+
const auto& ctor = cls.constructors[k];
|
|
1199
|
+
json << " {\"params\": [";
|
|
1200
|
+
for (size_t p = 0; p < ctor.param_types.size(); ++p) {
|
|
1201
|
+
json << "\"" << ctor.param_types[p] << "\"";
|
|
1202
|
+
if (p < ctor.param_types.size() - 1) json << ", ";
|
|
1203
|
+
}
|
|
1204
|
+
json << "]}";
|
|
1205
|
+
if (k < cls.constructors.size() - 1) json << ",";
|
|
1206
|
+
json << "\n";
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
json << " ]";
|
|
1210
|
+
|
|
1153
1211
|
json << ",\n \"methods\": [\n";
|
|
1154
1212
|
for (size_t k = 0; k < cls.methods.size(); ++k) {
|
|
1155
1213
|
const auto& method = cls.methods[k];
|
|
@@ -93,12 +93,18 @@ struct FieldInfo {
|
|
|
93
93
|
std::string documentation;
|
|
94
94
|
};
|
|
95
95
|
|
|
96
|
+
// v2.4.3: Constructor parameter types
|
|
97
|
+
struct ConstructorInfo {
|
|
98
|
+
std::vector<std::string> param_types; // e.g., ["double", "double"] for Vector2D(double, double)
|
|
99
|
+
};
|
|
100
|
+
|
|
96
101
|
struct ClassBinding {
|
|
97
102
|
std::string module_name;
|
|
98
103
|
std::string class_name;
|
|
99
104
|
std::vector<std::pair<std::string, std::string>> params;
|
|
100
105
|
std::vector<std::string> methods; // Method names to bind
|
|
101
106
|
std::vector<std::string> fields; // Field names to bind
|
|
107
|
+
std::vector<ConstructorInfo> constructors; // v2.4.3: Constructor overloads
|
|
102
108
|
bool auto_bind_all; // Bind all methods automatically
|
|
103
109
|
std::string documentation; // Class documentation from DOC()
|
|
104
110
|
std::map<std::string, std::string> method_docs; // Method-specific docs: method_name -> doc
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "IncludeCPP"
|
|
7
|
-
version = "2.4.
|
|
7
|
+
version = "2.4.3"
|
|
8
8
|
description = "Professional C++ Python bindings with type-generic templates, pystubs and native threading"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -6,7 +6,7 @@ long_description = (this_directory / "README.md").read_text(encoding="utf-8")
|
|
|
6
6
|
|
|
7
7
|
setup(
|
|
8
8
|
name="IncludeCPP",
|
|
9
|
-
version="2.4.
|
|
9
|
+
version="2.4.3",
|
|
10
10
|
author="IncludeCPP Team",
|
|
11
11
|
author_email="contact@includecpp.dev",
|
|
12
12
|
description="Professional C++ Python bindings with type-generic templates and native threading",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|