I see this behavior both with the C++ and Python API; certain objects will return false for isValid immediately after creation, e.g. the camera returned from Viewport (app.activeViewport.camera.isValid == False), the ParameterList returned from a design (app.activeProduct.allParameters.isValid == False, when a design is loaded). These objects are perfectly fine to use, except calling isValid will return false.
Is this expected, and there are only certain objects for which we should rely on isValid? Or is this a bug, and the expectation is that isValid will return true for all valid objects that extend Base?
That's a bug. The isValid property is on the Base class so everything in the API supports it, but in reality, it's not very useful for many of the objects. It's intended to indicate if the object you're holding still exists in a valid state. It doesn't mean the data within the object is good or bad. It's the most useful for B-Rep-related objects because you can hold a reference to an object like a face and then make changes to the model that will invalidate the face you're referencing. Other objects like a Point3D, Vector3D, and Camera are transient and will always be valid.
I'm fairly certain this has never been thoroughly tested and the behavior you're seeing is just an oversight that wasn't caught earlier.
In some contexts, it may be better to not throw an exception at all, but (IMO) You have also, very reasonably, defined the behavior of your class in one the most natural result for the last case - non-coinciding parallel lines.
Can't find what you're looking for? Ask the community or share your knowledge.