ortools.math_opt.python.from_model
Utilities for finding the model associated with a variable/constraint etc.
This file is an implementation detail and not part of the MathOpt public API.
1# Copyright 2010-2025 Google LLC 2# Licensed under the Apache License, Version 2.0 (the "License"); 3# you may not use this file except in compliance with the License. 4# You may obtain a copy of the License at 5# 6# http://www.apache.org/licenses/LICENSE-2.0 7# 8# Unless required by applicable law or agreed to in writing, software 9# distributed under the License is distributed on an "AS IS" BASIS, 10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11# See the License for the specific language governing permissions and 12# limitations under the License. 13 14"""Utilities for finding the model associated with a variable/constraint etc. 15 16This file is an implementation detail and not part of the MathOpt public API. 17""" 18 19from typing import Protocol 20from ortools.math_opt.python.elemental import elemental 21 22 23class FromModel(Protocol): 24 25 __slots__ = () 26 27 @property 28 def elemental(self) -> elemental.Elemental: ... 29 30 31def model_is_same(e1: FromModel, e2: FromModel) -> None: 32 if e1.elemental is not e2.elemental: 33 raise ValueError( 34 f"Expected two elements from the same model, but observed {e1} from" 35 f" model named: '{e1.elemental.model_name!r}', and {e2} from model" 36 f" named: '{e2.elemental.model_name!r}'." 37 )
class
FromModel(typing.Protocol):
24class FromModel(Protocol): 25 26 __slots__ = () 27 28 @property 29 def elemental(self) -> elemental.Elemental: ...
Base class for protocol classes.
Protocol classes are defined as::
class Proto(Protocol):
def meth(self) -> int:
...
Such classes are primarily used with static type checkers that recognize structural subtyping (static duck-typing).
For example::
class C:
def meth(self) -> int:
return 0
def func(x: Proto) -> int:
return x.meth()
func(C()) # Passes static type check
See PEP 544 for details. Protocol classes decorated with @typing.runtime_checkable act as simple-minded runtime protocols that check only the presence of given attributes, ignoring their type signatures. Protocol classes can be generic, they are defined as::
class GenProto[T](Protocol):
def meth(self) -> T:
...
FromModel(*args, **kwargs)
1945def _no_init_or_replace_init(self, *args, **kwargs): 1946 cls = type(self) 1947 1948 if cls._is_protocol: 1949 raise TypeError('Protocols cannot be instantiated') 1950 1951 # Already using a custom `__init__`. No need to calculate correct 1952 # `__init__` to call. This can lead to RecursionError. See bpo-45121. 1953 if cls.__init__ is not _no_init_or_replace_init: 1954 return 1955 1956 # Initially, `__init__` of a protocol subclass is set to `_no_init_or_replace_init`. 1957 # The first instantiation of the subclass will call `_no_init_or_replace_init` which 1958 # searches for a proper new `__init__` in the MRO. The new `__init__` 1959 # replaces the subclass' old `__init__` (ie `_no_init_or_replace_init`). Subsequent 1960 # instantiation of the protocol subclass will thus use the new 1961 # `__init__` and no longer call `_no_init_or_replace_init`. 1962 for base in cls.__mro__: 1963 init = base.__dict__.get('__init__', _no_init_or_replace_init) 1964 if init is not _no_init_or_replace_init: 1965 cls.__init__ = init 1966 break 1967 else: 1968 # should not happen 1969 cls.__init__ = object.__init__ 1970 1971 cls.__init__(self, *args, **kwargs)
32def model_is_same(e1: FromModel, e2: FromModel) -> None: 33 if e1.elemental is not e2.elemental: 34 raise ValueError( 35 f"Expected two elements from the same model, but observed {e1} from" 36 f" model named: '{e1.elemental.model_name!r}', and {e2} from model" 37 f" named: '{e2.elemental.model_name!r}'." 38 )