Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for assigning to non-existent variables (#1708) #1718

Merged
merged 7 commits into from
Jul 16, 2024
31 changes: 25 additions & 6 deletions libexec/trick/convert_swig
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,24 @@ sub process_file() {
print OUT "\n$new_contents" ;
print OUT "$contents\n" ;
print OUT $global_template_typedefs ;

# Add _swig_setattr_nondynamic_instance_variable function for raising AttributeError for improper non-class attribute assingment in input processor.
# _swig_setattr_nondynamic_instance_variable function is added for each class in process_class subroutine.
foreach my $c ( @class_names ) {
if ( ! exists $class_typemap_printed{$c} ) {
my $c_ = $c ;
$c_ =~ s/\:/_/g ;
if ( $c !~ /::/ ) {
print OUT "\n#if SWIG_VERSION > 0x040000\n";
print OUT "%pythoncode %{\n" ;
print OUT " if '$c' in globals():\n";
print OUT " $c.__setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n" ;
print OUT "%}\n" ;
print OUT "#endif\n";
}
}
}

# Add a trick_cast_as macro line for each class parsed in the file. These lines must appear at the bottom of the
# file to ensure they are not in a namespace directive and they are after the #define statements they depend on.
undef %class_typemap_printed ;
Expand Down Expand Up @@ -479,6 +497,9 @@ sub process_template($$) {
my ( $contents_ref , $new_contents_ref ) = @_ ;
my $extracted ;

# Add _swig_setattr_nondynamic_instance_variable function for raising AttributeError for improper class attribute assingment in input processor
# The function call is inserted after the 1st { of the class template so it is placed at the top
$$contents_ref=~s/{\n/{\n\n#if SWIG_VERSION > 0x040000\n\%pythoncode \%{\n __setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n\%}\n#endif\n/m;
if ( $$contents_ref =~ s/^(\s*;)//s ) {
$$new_contents_ref .= $1 ;
} else {
Expand Down Expand Up @@ -605,6 +626,9 @@ sub process_class($$$$$) {
$class_content .= $1 ;
}

# Add _swig_setattr_nondynamic_instance_variable function for raising AttributeError for improper class attribute assingment in input processor
$class_content .= "\n#if SWIG_VERSION > 0x040000\n\%pythoncode \%{\n __setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n\%}\n#endif\n" ;

($extracted, $$contents_ref) = extract_bracketed( "{" . $$contents_ref , "{}") ;

# remove the trailing semicolon because we may append text to the class.
Expand Down Expand Up @@ -709,7 +733,6 @@ sub process_class($$$$$) {
push @$class_names_ref , "$curr_namespace$class_name" ;

# write the class contents and semicolon to ensure any template declarations below are after the semicolon.
$class_content .= "\n#if SWIG_VERSION > 0x040000\n\%pythoncode \%{\n __setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n\%}\n#endif\n" ;
$class_content .= $extracted . ";\n" ;

my $c_ = "$curr_namespace$class_name" ;
Expand Down Expand Up @@ -756,7 +779,7 @@ sub process_typedef_struct($$$$) {
my ($typedef_struct_string , $contents_ref, $new_contents_ref , $class_names_ref) = @_ ;

my $extracted ;
my ($begin, $tail , $struct_names, @struct_names) ;
my ($tail , $struct_names, @struct_names) ;

#print "*** typedef_struct_string = $typedef_struct_string ***\n" ;

Expand All @@ -765,7 +788,6 @@ sub process_typedef_struct($$$$) {
$typedef_struct_string =~ s/((?:typedef\s+)?(struct|union)\s* # the words typedef struct|union
([_A-Za-z]\w*)?\s* # optional name
{)//sx ;
$begin = $3 ;

($extracted, $$contents_ref) = extract_bracketed( "{" . $$contents_ref , "{}") ;
#print "*** extracted = $extracted ***\n" ;
Expand All @@ -780,9 +802,6 @@ sub process_typedef_struct($$$$) {
$struct_names =~ s/\s//g ;
@struct_names = split /,/ , $struct_names ;

if ( $begin ne "" ) {
push @$class_names_ref , $begin ;
}
foreach my $s ( @struct_names ) {
if ( $s !~ /\*/ ) {
push @$class_names_ref , $s ;
Expand Down
16 changes: 16 additions & 0 deletions trick_source/trick_swig/swig_double.i
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,19 @@ class swig_double {
PyObject * __len__() ;
} ;

%pythoncode %{
#if SWIG_VERSION > 0x040000
def _trick_setattr_nondynamic_instance_variable(set):
def set_instance_attr(self, name, value):
if name == "thisown":
self.this.own(value)
elif name == "this":
set(self, name, value)
else:
msg = f'You cannot add instance attribute \'{name}\' to Trick swig_double'
raise AttributeError(msg)
return set_instance_attr

swig_double.__setattr__ = _trick_setattr_nondynamic_instance_variable(object.__setattr__)
#endif
%}
16 changes: 16 additions & 0 deletions trick_source/trick_swig/swig_int.i
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,19 @@ class swig_int {
PyObject * __bool__() ;
} ;

%pythoncode %{
#if SWIG_VERSION > 0x040000
def _trick_setattr_nondynamic_instance_variable(set):
def set_instance_attr(self, name, value):
if name == "thisown":
self.this.own(value)
elif name == "this":
set(self, name, value)
else:
msg = f'You cannot add instance attribute \'{name}\' to Trick swig_int'
raise AttributeError(msg)
return set_instance_attr

swig_int.__setattr__ = _trick_setattr_nondynamic_instance_variable(object.__setattr__)
#endif
%}
Loading