Python is wonderfully terrible that methods, and variables can added on the fly. This makes it less like java, but means that typos can go undetected by python. For instance model.goemetry = new_geom would be totally fine, but can and does cause user frustration with debugging. So I propose we somehow enforce the allowed variables for some subset of classes in the python api so that the above example would raise AttributeError.
The most "traditional" approach is to switch from __dict__ to __slots__. I won't get into the nuance as I'm not an expert. The key points are:
This would accomplish the goal
You have to explicitly list all variables for the classes you want to do this with.
This would something like:
class Model:
__slots__ = ("geometry", ...)
Or so it would seem. However, methods get automatically added, so @property doesn't need to be added, just hidden ones. So this would actually be more like:
class Model:
__slots__ = ("_geometry", ...)
@property
def geometry(self):
pass
The other option is to override __setattr__ and do some enforcement. Something like:
def __setattr__(self, key, value):
try:
self.key
self.__dict__[key] = value
except AttributeError as e:
raise AttributeError(f"Es ist verboden! ...") from e
This latter option would require less code, they it doesn't feel as clean. It isn't not pythonic though, I think.
Compatibility
The biggest issue I see is some users may view this as a feature and not a bug, and like to add random attributes to their openmc model. In that case we could an option to change these errors into Warnings.
Description
Python is wonderfully terrible that methods, and variables can added on the fly. This makes it less like java, but means that typos can go undetected by python. For instance
model.goemetry = new_geom
would be totally fine, but can and does cause user frustration with debugging. So I propose we somehow enforce the allowed variables for some subset of classes in the python api so that the above example would raiseAttributeError
.There a few ways to go about this that I've discussed before for MontePy.
The most "traditional" approach is to switch from
__dict__
to__slots__
. I won't get into the nuance as I'm not an expert. The key points are:This would something like:
Or so it would seem. However, methods get automatically added, so
@property
doesn't need to be added, just hidden ones. So this would actually be more like:The other option is to override
__setattr__
and do some enforcement. Something like:This latter option would require less code, they it doesn't feel as clean. It isn't not pythonic though, I think.
Compatibility
The biggest issue I see is some users may view this as a feature and not a bug, and like to add random attributes to their openmc model. In that case we could an option to change these errors into Warnings.