Skip to content

Create custom setattr for most python objects #2920

@MicahGale

Description

@MicahGale

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions