
On Fri, Sep 02, 2022 at 12:53:47AM -0000, Steve Jorgensen wrote:
I didn't say that I was talking about a file. In fact, today, I'm talking about an object that manages a subprocess. If a caller tries to call a method of the manager to interact with the subprocess when the subprocess has not yet been started or after it has been terminated, then I want to raise an appropriate exception.
Your API shouldn't allow the object to be created and returned until it has been started. Long ago I read a great blog post describing this idiom as an anti-pattern: obj = SomeObject(args) obj.make_it_work() obj.do_something() where constructing the object isn't sufficient to start using it, you have to call a second, magical method (sometimes called "init()"!) to make it actually usable. Unfortunately I lost the URL and have never been able to find it again, but it made a big impression on me. You will notice that we don't do that with Python builtins: # we don't do this! f = open('filename', 'w') f.open() # Actually open it for writing. f.write('stuff') # Or this: d = dict(key=value) d.init() # Can't use the dict until we make it work. d.update(something) Returning a dict in an initialiated but invalid state, which needs a second method call to make it valid, would be an obvious antipattern. Why would we do such a thing? Its a bad design! Just have the dict constuctor return the dict in the fully valid state. Which of course we do: for most (all?) objects in the stdlib, creating the object *fully* initialises it, so it is ready to use, immediately, without needing a special "make it work" method call. Of course there may be some exceptions to that rule, but they are uncommon.
I am raising a custom exception, and it annoys me that it has to simply inherit from Exception when I think that an invalid state condition is a common enough kind of issue that it should have a standard exception class in the hierarchy.
Perhaps you should take your lead from file objects and inherit from ValueError. Trying to interact with a terminated process is analogous to writing to a closed file. What sort of features or APIs do you expect to inherit from this InvalidStateError class? -- Steve