ortools.math_opt.python.errors
Translate C++'s absl::Status errors to Python standard errors.
Here we try to use the standard Python errors we would use if the C++ code was instead implemented in Python. This will give Python users a more familiar API.
1#!/usr/bin/env python3 2# Copyright 2010-2025 Google LLC 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15"""Translate C++'s absl::Status errors to Python standard errors. 16 17Here we try to use the standard Python errors we would use if the C++ code was 18instead implemented in Python. This will give Python users a more familiar API. 19""" 20 21import enum 22from typing import Optional, Type 23from ortools.math_opt import rpc_pb2 24 25 26class _StatusCode(enum.Enum): 27 """The C++ absl::Status::code() values.""" 28 29 OK = 0 30 CANCELLED = 1 31 UNKNOWN = 2 32 INVALID_ARGUMENT = 3 33 DEADLINE_EXCEEDED = 4 34 NOT_FOUND = 5 35 ALREADY_EXISTS = 6 36 PERMISSION_DENIED = 7 37 UNAUTHENTICATED = 16 38 RESOURCE_EXHAUSTED = 8 39 FAILED_PRECONDITION = 9 40 ABORTED = 10 41 OUT_OF_RANGE = 11 42 UNIMPLEMENTED = 12 43 INTERNAL = 13 44 UNAVAILABLE = 14 45 DATA_LOSS = 15 46 47 48class InternalMathOptError(RuntimeError): 49 """Some MathOpt internal error. 50 51 This error is usually raised because of a bug in MathOpt or one of the solver 52 library it wraps. 53 """ 54 55 56def status_proto_to_exception( 57 status_proto: rpc_pb2.StatusProto, 58) -> Optional[Exception]: 59 """Returns the Python exception that best match the input absl::Status. 60 61 There are some Status that we expect the MathOpt code to return, for those the 62 matching exceptions are: 63 - InvalidArgument: ValueError 64 - FailedPrecondition: AssertionError 65 - Unimplemented: NotImplementedError 66 - Internal: InternalMathOptError 67 68 Other Status's are not used by MathOpt, if they are seen a 69 InternalMathOptError is raised (as if the Status was Internal) and the error 70 message contains the unexpected code. 71 72 Args: 73 status_proto: The input proto to convert to an exception. 74 75 Returns: 76 The corresponding exception. None if the input status is OK. 77 """ 78 try: 79 code = _StatusCode(status_proto.code) 80 except ValueError: 81 return InternalMathOptError( 82 f"unknown C++ error (code = {status_proto.code}):" 83 f" {status_proto.message}" 84 ) 85 86 if code == _StatusCode.OK: 87 return None 88 89 # For expected errors we compute the corresponding class. 90 error_type: Optional[Type[Exception]] = None 91 if code == _StatusCode.INVALID_ARGUMENT: 92 error_type = ValueError 93 if code == _StatusCode.FAILED_PRECONDITION: 94 error_type = AssertionError 95 if code == _StatusCode.UNIMPLEMENTED: 96 error_type = NotImplementedError 97 if code == _StatusCode.INTERNAL: 98 error_type = InternalMathOptError 99 100 if error_type is not None: 101 return error_type(f"{status_proto.message} (was C++ {code.name})") 102 103 return InternalMathOptError( 104 f"unexpected C++ error {code.name}: {status_proto.message}" 105 )
class
InternalMathOptError(builtins.RuntimeError):
49class InternalMathOptError(RuntimeError): 50 """Some MathOpt internal error. 51 52 This error is usually raised because of a bug in MathOpt or one of the solver 53 library it wraps. 54 """
Some MathOpt internal error.
This error is usually raised because of a bug in MathOpt or one of the solver library it wraps.
def
status_proto_to_exception(status_proto: ortools.math_opt.rpc_pb2.StatusProto) -> Exception | None:
57def status_proto_to_exception( 58 status_proto: rpc_pb2.StatusProto, 59) -> Optional[Exception]: 60 """Returns the Python exception that best match the input absl::Status. 61 62 There are some Status that we expect the MathOpt code to return, for those the 63 matching exceptions are: 64 - InvalidArgument: ValueError 65 - FailedPrecondition: AssertionError 66 - Unimplemented: NotImplementedError 67 - Internal: InternalMathOptError 68 69 Other Status's are not used by MathOpt, if they are seen a 70 InternalMathOptError is raised (as if the Status was Internal) and the error 71 message contains the unexpected code. 72 73 Args: 74 status_proto: The input proto to convert to an exception. 75 76 Returns: 77 The corresponding exception. None if the input status is OK. 78 """ 79 try: 80 code = _StatusCode(status_proto.code) 81 except ValueError: 82 return InternalMathOptError( 83 f"unknown C++ error (code = {status_proto.code}):" 84 f" {status_proto.message}" 85 ) 86 87 if code == _StatusCode.OK: 88 return None 89 90 # For expected errors we compute the corresponding class. 91 error_type: Optional[Type[Exception]] = None 92 if code == _StatusCode.INVALID_ARGUMENT: 93 error_type = ValueError 94 if code == _StatusCode.FAILED_PRECONDITION: 95 error_type = AssertionError 96 if code == _StatusCode.UNIMPLEMENTED: 97 error_type = NotImplementedError 98 if code == _StatusCode.INTERNAL: 99 error_type = InternalMathOptError 100 101 if error_type is not None: 102 return error_type(f"{status_proto.message} (was C++ {code.name})") 103 104 return InternalMathOptError( 105 f"unexpected C++ error {code.name}: {status_proto.message}" 106 )
Returns the Python exception that best match the input absl::Status.
There are some Status that we expect the MathOpt code to return, for those the matching exceptions are:
- InvalidArgument: ValueError
- FailedPrecondition: AssertionError
- Unimplemented: NotImplementedError
- Internal: InternalMathOptError
Other Status's are not used by MathOpt, if they are seen a InternalMathOptError is raised (as if the Status was Internal) and the error message contains the unexpected code.
Arguments:
- status_proto: The input proto to convert to an exception.
Returns:
The corresponding exception. None if the input status is OK.