You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, processes have a defaults class variable that specifies the parameters they expect. Then when calling a process, you can provide parameters in a dictionary to the parameters argument to override those defaults. For example:
Our current approach for handling process parameters and defaults has a number of issues:
Parameters do not have types, which prevents type checking from catching typing errors. For example, you could write MyProcess({'flag': 'test'}) without raising any type errors.
Similarly, we don't actually enforce the convention that all accepted parameters be present in defaults. For example, MyProcess could have a next_update that uses self.parameters['flag2'] even though MyProcess.defaults does not contain flag2.
Other Python tools don't understand our way of specifying parameters. This means that e.g. PyCharm won't suggest parameters when you initialize a process.
Our approach is not the standard Python way of specifying parameters, which is confusing.
defaults are not handled correctly when subclassing processes. For example, consider the process class MyProcess2(MyProcess) with a constructor that calls MyProcess.__init__(parameters). Inside MyProcess.__init__, self.defaults refers to MyProcess2.defaults, not MyProcess.defaults like you'd expect.
Functionality to Preserve
Backwards compatibility. We don't want to have to rewrite all our libraries.
Ability to save off parameters for serialization.
Possible Alternative
All the problems would be solved by using normal Python function arguments for process parameters. Here's how we could preserve the desired functionality:
Not sure how we can do this yet.
I think we can use inspect and locals() to do this. We would, in Process.__init__(), first use self.__class__ to get the subclass. Then we could use code like this to get the parameters passed to the subclass constructor:
Is the only required backwards compatibility to support a self.defaults dict and a parameters dict being passed to the Process superclass with super().__init__(parameters)? Anything else?
Is the only purpose of having the Process superclass access the subclass locals to save these parameters for serialization?
I think we also need to handle of special parameters like time_step and _original_parameters, and we need to be able to access parameters through self.parameters.
The Process superclass also performs other operations like handling those special parameters, schema overrides, and merging the provided parameters with the defaults. More broadly though, the Process class adds a layer of indirection into which we can insert code to make changes based on what the user does. For example, we use get_schema() to apply schema overrides on top of what the user specifies in ports_schema().
Status Quo
Current Approach
Currently, processes have a
defaults
class variable that specifies the parameters they expect. Then when calling a process, you can provide parameters in a dictionary to theparameters
argument to override those defaults. For example:Problems with Current Approach
Our current approach for handling process parameters and defaults has a number of issues:
MyProcess({'flag': 'test'})
without raising any type errors.defaults
. For example,MyProcess
could have anext_update
that usesself.parameters['flag2']
even thoughMyProcess.defaults
does not containflag2
.defaults
are not handled correctly when subclassing processes. For example, consider the processclass MyProcess2(MyProcess)
with a constructor that callsMyProcess.__init__(parameters)
. InsideMyProcess.__init__
,self.defaults
refers toMyProcess2.defaults
, notMyProcess.defaults
like you'd expect.Functionality to Preserve
Possible Alternative
All the problems would be solved by using normal Python function arguments for process parameters. Here's how we could preserve the desired functionality:
Not sure how we can do this yet.
I think we can use
inspect
andlocals()
to do this. We would, inProcess.__init__()
, first useself.__class__
to get the subclass. Then we could use code like this to get the parameters passed to the subclass constructor:Source: https://stackoverflow.com/a/10724602
Note that the
locals()
call would have to happen in the subclass, and the result would need to be passed to the superclass constructor.The text was updated successfully, but these errors were encountered: