@@ -2623,7 +2623,8 @@ write_module_class(ostream &out, Object *obj) {
2623
2623
for (pit = obj->_properties .begin (); pit != obj->_properties .end (); ++pit) {
2624
2624
Property *property = (*pit);
2625
2625
const InterrogateElement &ielem = property->_ielement ;
2626
- if (property->_getter == NULL || !is_function_legal (property->_getter )) {
2626
+ if (!property->_has_this ||
2627
+ property->_getter == NULL || !is_function_legal (property->_getter )) {
2627
2628
continue ;
2628
2629
}
2629
2630
@@ -3169,6 +3170,45 @@ write_module_class(ostream &out, Object *obj) {
3169
3170
}
3170
3171
}
3171
3172
3173
+ // Also add the static properties, which can't be added via getset.
3174
+ Properties::const_iterator pit;
3175
+ for (pit = obj->_properties .begin (); pit != obj->_properties .end (); ++pit) {
3176
+ Property *property = (*pit);
3177
+ const InterrogateElement &ielem = property->_ielement ;
3178
+ if (property->_has_this ||
3179
+ property->_getter == NULL || !is_function_legal (property->_getter )) {
3180
+ continue ;
3181
+ }
3182
+
3183
+ string name1 = methodNameFromCppName (ielem.get_name (), " " , false );
3184
+ // string name2 = methodNameFromCppName(ielem.get_name(), "", true);
3185
+
3186
+ string getter = " &Dtool_" + ClassName + " _" + ielem.get_name () + " _Getter" ;
3187
+ string setter = " NULL" ;
3188
+ if (property->_length_function == NULL &&
3189
+ property->_setter != NULL && is_function_legal (property->_setter )) {
3190
+ setter = " &Dtool_" + ClassName + " _" + ielem.get_name () + " _Setter" ;
3191
+ }
3192
+
3193
+ out << " static const PyGetSetDef def_" << name1 << " = {(char *)\" " << name1 << " \" , " << getter << " , " << setter;
3194
+
3195
+ if (ielem.has_comment ()) {
3196
+ out << " , (char *)\n " ;
3197
+ output_quoted (out, 4 , ielem.get_comment ());
3198
+ out << " ,\n " ;
3199
+ } else {
3200
+ out << " , NULL, " ;
3201
+ }
3202
+
3203
+ // Extra void* argument; we don't make use of it.
3204
+ out << " NULL};\n " ;
3205
+
3206
+ out << " PyDict_SetItemString(dict, \" " << name1 << " \" , Dtool_NewStaticProperty(&Dtool_" << ClassName << " ._PyType, &def_" << name1 << " ));\n " ;
3207
+ /* Alternative spelling:
3208
+ out << " PyDict_SetItemString(\"" << name2 << "\", &def_" << name1 << ");\n";
3209
+ */
3210
+ }
3211
+
3172
3212
out << " if (PyType_Ready((PyTypeObject *)&Dtool_" << ClassName << " ) < 0) {\n "
3173
3213
" Dtool_Raise_TypeError(\" PyType_Ready(" << ClassName << " )\" );\n "
3174
3214
" return;\n "
@@ -6443,11 +6483,15 @@ write_getset(ostream &out, Object *obj, Property *property) {
6443
6483
" /**\n "
6444
6484
" * sequence getter for property " << cClassName << " ::" << ielem.get_name () << " \n "
6445
6485
" */\n "
6446
- " static PyObject *Dtool_" + ClassName + " _" + ielem.get_name () + " _Getitem(PyObject *self, Py_ssize_t index) {\n "
6447
- " " << cClassName << " *local_this = NULL;\n "
6448
- " if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << " , (void **)&local_this)) {\n "
6449
- " return NULL;\n "
6450
- " }\n " ;
6486
+ " static PyObject *Dtool_" + ClassName + " _" + ielem.get_name () + " _Getitem(PyObject *self, Py_ssize_t index) {\n " ;
6487
+ if (property->_getter ->_has_this ||
6488
+ (property->_has_function && property->_has_function ->_has_this )) {
6489
+ out <<
6490
+ " " << cClassName << " *local_this = NULL;\n "
6491
+ " if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << " , (void **)&local_this)) {\n "
6492
+ " return NULL;\n "
6493
+ " }\n " ;
6494
+ }
6451
6495
6452
6496
// This is a getitem of a sequence type. This means we *need* to raise
6453
6497
// IndexError if we're out of bounds.
@@ -6458,8 +6502,12 @@ write_getset(ostream &out, Object *obj, Property *property) {
6458
6502
out << " }\n " ;
6459
6503
6460
6504
if (property->_has_function != NULL ) {
6461
- out << " if (!local_this->" << property->_has_function ->_ifunc .get_name () << " (index)) {\n "
6462
- << " Py_INCREF(Py_None);\n "
6505
+ if (property->_has_function ->_has_this ) {
6506
+ out << " if (!local_this->" << property->_has_function ->_ifunc .get_name () << " (index)) {\n " ;
6507
+ } else {
6508
+ out << " if (!" << cClassName << " ::" << property->_has_function ->_ifunc .get_name () << " (index)) {\n " ;
6509
+ }
6510
+ out << " Py_INCREF(Py_None);\n "
6463
6511
<< " return Py_None;\n "
6464
6512
<< " }\n " ;
6465
6513
}
@@ -6494,26 +6542,36 @@ write_getset(ostream &out, Object *obj, Property *property) {
6494
6542
// Write out a setitem if this is not a read-only property.
6495
6543
if (property->_setter != NULL ) {
6496
6544
out << " static int Dtool_" + ClassName + " _" + ielem.get_name () + " _Setitem(PyObject *self, Py_ssize_t index, PyObject *arg) {\n " ;
6497
- out << " " << cClassName << " *local_this = NULL;\n " ;
6498
- out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << " , (void **)&local_this, \" "
6499
- << classNameFromCppName (cClassName, false ) << " ." << ielem.get_name () << " \" )) {\n " ;
6500
- out << " return -1;\n " ;
6501
- out << " }\n\n " ;
6545
+ if (property->_has_this ) {
6546
+ out << " " << cClassName << " *local_this = NULL;\n " ;
6547
+ out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << " , (void **)&local_this, \" "
6548
+ << classNameFromCppName (cClassName, false ) << " ." << ielem.get_name () << " \" )) {\n " ;
6549
+ out << " return -1;\n " ;
6550
+ out << " }\n\n " ;
6551
+ }
6502
6552
6503
6553
out << " if (arg == (PyObject *)NULL) {\n " ;
6504
6554
if (property->_deleter != NULL ) {
6505
- out << " local_this->" << property->_deleter ->_ifunc .get_name () << " (index);\n "
6506
- << " return 0;\n " ;
6555
+ if (property->_deleter ->_has_this ) {
6556
+ out << " local_this->" << property->_deleter ->_ifunc .get_name () << " (index);\n " ;
6557
+ } else {
6558
+ out << " " << cClassName << " ::" << property->_deleter ->_ifunc .get_name () << " (index);\n " ;
6559
+ }
6560
+ out << " return 0;\n " ;
6507
6561
} else {
6508
6562
out << " Dtool_Raise_TypeError(\" can't delete " << ielem.get_name () << " [] attribute\" );\n "
6509
6563
" return -1;\n " ;
6510
6564
}
6511
6565
out << " }\n " ;
6512
6566
6513
6567
if (property->_clear_function != NULL ) {
6514
- out << " if (arg == Py_None) {\n "
6515
- << " local_this->" << property->_clear_function ->_ifunc .get_name () << " (index);\n "
6516
- << " return 0;\n "
6568
+ out << " if (arg == Py_None) {\n " ;
6569
+ if (property->_clear_function ->_has_this ) {
6570
+ out << " local_this->" << property->_clear_function ->_ifunc .get_name () << " (index);\n " ;
6571
+ } else {
6572
+ out << " " << cClassName << " ::" << property->_clear_function ->_ifunc .get_name () << " (index);\n " ;
6573
+ }
6574
+ out << " return 0;\n "
6517
6575
<< " }\n " ;
6518
6576
}
6519
6577
@@ -6547,9 +6605,14 @@ write_getset(ostream &out, Object *obj, Property *property) {
6547
6605
}
6548
6606
6549
6607
// Now write the getter, which returns a special wrapper object.
6550
- out << " static PyObject *Dtool_" + ClassName + " _" + ielem.get_name () + " _Getter(PyObject *self, void *) {\n "
6551
- " Py_INCREF(self);\n "
6552
- " Dtool_SequenceWrapper *wrap = PyObject_New(Dtool_SequenceWrapper, &Dtool_SequenceWrapper_Type);\n "
6608
+ out << " static PyObject *Dtool_" + ClassName + " _" + ielem.get_name () + " _Getter(PyObject *self, void *) {\n " ;
6609
+ if (property->_has_this ) {
6610
+ out << " nassertr(self != NULL, NULL);\n "
6611
+ " Py_INCREF(self);\n " ;
6612
+ } else {
6613
+ out << " Py_XINCREF(self);\n " ;
6614
+ }
6615
+ out << " Dtool_SequenceWrapper *wrap = PyObject_New(Dtool_SequenceWrapper, &Dtool_SequenceWrapper_Type);\n "
6553
6616
" wrap->_base = self;\n "
6554
6617
" wrap->_len_func = &Dtool_" << ClassName << " _" << ielem.get_name () << " _Len;\n "
6555
6618
" wrap->_getitem_func = &Dtool_" << ClassName << " _" << ielem.get_name () << " _Getitem;\n " ;
@@ -6566,20 +6629,26 @@ write_getset(ostream &out, Object *obj, Property *property) {
6566
6629
out << " static PyObject *Dtool_" + ClassName + " _" + ielem.get_name () + " _Getter(PyObject *self, void *) {\n " ;
6567
6630
FunctionRemap *remap = property->_getter ->_remaps .front ();
6568
6631
6569
- if (remap->_const_method ) {
6570
- out << " const " << cClassName << " *local_this = NULL;\n " ;
6571
- out << " if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << " , (void **)&local_this)) {\n " ;
6572
- } else {
6573
- out << " " << cClassName << " *local_this = NULL;\n " ;
6574
- out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << " , (void **)&local_this, \" "
6575
- << classNameFromCppName (cClassName, false ) << " ." << ielem.get_name () << " \" )) {\n " ;
6632
+ if (remap->_has_this ) {
6633
+ if (remap->_const_method ) {
6634
+ out << " const " << cClassName << " *local_this = NULL;\n " ;
6635
+ out << " if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << " , (void **)&local_this)) {\n " ;
6636
+ } else {
6637
+ out << " " << cClassName << " *local_this = NULL;\n " ;
6638
+ out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << " , (void **)&local_this, \" "
6639
+ << classNameFromCppName (cClassName, false ) << " ." << ielem.get_name () << " \" )) {\n " ;
6640
+ }
6641
+ out << " return NULL;\n " ;
6642
+ out << " }\n\n " ;
6576
6643
}
6577
- out << " return NULL;\n " ;
6578
- out << " }\n\n " ;
6579
6644
6580
6645
if (property->_has_function != NULL ) {
6581
- out << " if (!local_this->" << property->_has_function ->_ifunc .get_name () << " ()) {\n "
6582
- << " Py_INCREF(Py_None);\n "
6646
+ if (remap->_has_this ) {
6647
+ out << " if (!local_this->" << property->_has_function ->_ifunc .get_name () << " ()) {\n " ;
6648
+ } else {
6649
+ out << " if (!" << cClassName << " ::" << property->_has_function ->_ifunc .get_name () << " ()) {\n " ;
6650
+ }
6651
+ out << " Py_INCREF(Py_None);\n "
6583
6652
<< " return Py_None;\n "
6584
6653
<< " }\n " ;
6585
6654
}
@@ -6596,26 +6665,35 @@ write_getset(ostream &out, Object *obj, Property *property) {
6596
6665
// Write out a setter if this is not a read-only property.
6597
6666
if (property->_setter != NULL ) {
6598
6667
out << " static int Dtool_" + ClassName + " _" + ielem.get_name () + " _Setter(PyObject *self, PyObject *arg, void *) {\n " ;
6599
- out << " " << cClassName << " *local_this = NULL;\n " ;
6600
- out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << " , (void **)&local_this, \" "
6601
- << classNameFromCppName (cClassName, false ) << " ." << ielem.get_name () << " \" )) {\n " ;
6602
- out << " return -1;\n " ;
6603
- out << " }\n\n " ;
6668
+ if (remap->_has_this ) {
6669
+ out << " " << cClassName << " *local_this = NULL;\n " ;
6670
+ out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << " , (void **)&local_this, \" "
6671
+ << classNameFromCppName (cClassName, false ) << " ." << ielem.get_name () << " \" )) {\n " ;
6672
+ out << " return -1;\n " ;
6673
+ out << " }\n\n " ;
6674
+ }
6604
6675
6605
6676
out << " if (arg == (PyObject *)NULL) {\n " ;
6606
- if (property->_deleter != NULL ) {
6677
+ if (property->_deleter != NULL && remap-> _has_this ) {
6607
6678
out << " local_this->" << property->_deleter ->_ifunc .get_name () << " ();\n "
6608
6679
<< " return 0;\n " ;
6680
+ } else if (property->_deleter != NULL ) {
6681
+ out << " " << cClassName << " ::" << property->_deleter ->_ifunc .get_name () << " ();\n "
6682
+ << " return 0;\n " ;
6609
6683
} else {
6610
6684
out << " Dtool_Raise_TypeError(\" can't delete " << ielem.get_name () << " attribute\" );\n "
6611
6685
" return -1;\n " ;
6612
6686
}
6613
6687
out << " }\n " ;
6614
6688
6615
6689
if (property->_clear_function != NULL ) {
6616
- out << " if (arg == Py_None) {\n "
6617
- << " local_this->" << property->_clear_function ->_ifunc .get_name () << " ();\n "
6618
- << " return 0;\n "
6690
+ out << " if (arg == Py_None) {\n " ;
6691
+ if (remap->_has_this ) {
6692
+ out << " local_this->" << property->_clear_function ->_ifunc .get_name () << " ();\n " ;
6693
+ } else {
6694
+ out << " " << cClassName << " ::" << property->_clear_function ->_ifunc .get_name () << " ();\n " ;
6695
+ }
6696
+ out << " return 0;\n "
6619
6697
<< " }\n " ;
6620
6698
}
6621
6699
@@ -6744,6 +6822,7 @@ record_object(TypeIndex type_index) {
6744
6822
Function *setter = record_function (itype, func_index);
6745
6823
if (is_function_legal (setter)) {
6746
6824
property->_setter = setter;
6825
+ property->_has_this |= setter->_has_this ;
6747
6826
}
6748
6827
}
6749
6828
@@ -6752,6 +6831,7 @@ record_object(TypeIndex type_index) {
6752
6831
Function *getter = record_function (itype, func_index);
6753
6832
if (is_function_legal (getter)) {
6754
6833
property->_getter = getter;
6834
+ property->_has_this |= getter->_has_this ;
6755
6835
}
6756
6836
}
6757
6837
@@ -6760,6 +6840,7 @@ record_object(TypeIndex type_index) {
6760
6840
Function *has_function = record_function (itype, func_index);
6761
6841
if (is_function_legal (has_function)) {
6762
6842
property->_has_function = has_function;
6843
+ property->_has_this |= has_function->_has_this ;
6763
6844
}
6764
6845
}
6765
6846
@@ -6768,6 +6849,7 @@ record_object(TypeIndex type_index) {
6768
6849
Function *clear_function = record_function (itype, func_index);
6769
6850
if (is_function_legal (clear_function)) {
6770
6851
property->_clear_function = clear_function;
6852
+ property->_has_this |= clear_function->_has_this ;
6771
6853
}
6772
6854
}
6773
6855
@@ -6776,12 +6858,16 @@ record_object(TypeIndex type_index) {
6776
6858
Function *del_function = record_function (itype, func_index);
6777
6859
if (is_function_legal (del_function)) {
6778
6860
property->_deleter = del_function;
6861
+ property->_has_this |= del_function->_has_this ;
6779
6862
}
6780
6863
}
6781
6864
6782
6865
if (ielement.is_sequence ()) {
6783
6866
FunctionIndex func_index = ielement.get_length_function ();
6784
6867
property->_length_function = record_function (itype, func_index);
6868
+ if (property->_length_function != nullptr ) {
6869
+ property->_has_this |= property->_length_function ->_has_this ;
6870
+ }
6785
6871
}
6786
6872
6787
6873
if (property->_getter != NULL ) {
0 commit comments