openmc-dev / openmc

OpenMC Monte Carlo Code
https://docs.openmc.org
Other
699 stars 444 forks source link

Disable setattr for most python objects #2920

Open MicahGale opened 1 month ago

MicahGale commented 1 month ago

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 raise AttributeError.

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:

  1. This would accomplish the goal
  2. 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.