ValueError is the best thing to raise in this case. For python, you should prefer using the built-in exception types over creating your own. You should only create new exception types when you expect that you will need to catch it and behave very differently than you’d behave when catching the builtin types. In this case, the situation shouldn’t arise – you’re not expecting to catch this because it would indicate an error in using the class in question. For this it’s not worth creating a new type just to make it have another name – that’s what the message string that you pass to
ValueError() is for.
Is it possible to restructure your class so that such an invalid state is not possible?