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#!/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"""Utilities for finding the model associated with a variable/constraint etc. 16 17This file is an implementation detail and not part of the MathOpt public API. 18""" 19 20from typing import Protocol 21from ortools.math_opt.python.elemental import elemental 22 23 24class FromModel(Protocol): 25 26 __slots__ = () 27 28 @property 29 def elemental(self) -> elemental.Elemental: ... 30 31 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 )
class
FromModel(typing.Protocol):
25class FromModel(Protocol): 26 27 __slots__ = () 28 29 @property 30 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)
1866def _no_init_or_replace_init(self, *args, **kwargs): 1867 cls = type(self) 1868 1869 if cls._is_protocol: 1870 raise TypeError('Protocols cannot be instantiated') 1871 1872 # Already using a custom `__init__`. No need to calculate correct 1873 # `__init__` to call. This can lead to RecursionError. See bpo-45121. 1874 if cls.__init__ is not _no_init_or_replace_init: 1875 return 1876 1877 # Initially, `__init__` of a protocol subclass is set to `_no_init_or_replace_init`. 1878 # The first instantiation of the subclass will call `_no_init_or_replace_init` which 1879 # searches for a proper new `__init__` in the MRO. The new `__init__` 1880 # replaces the subclass' old `__init__` (ie `_no_init_or_replace_init`). Subsequent 1881 # instantiation of the protocol subclass will thus use the new 1882 # `__init__` and no longer call `_no_init_or_replace_init`. 1883 for base in cls.__mro__: 1884 init = base.__dict__.get('__init__', _no_init_or_replace_init) 1885 if init is not _no_init_or_replace_init: 1886 cls.__init__ = init 1887 break 1888 else: 1889 # should not happen 1890 cls.__init__ = object.__init__ 1891 1892 cls.__init__(self, *args, **kwargs)
33def model_is_same(e1: FromModel, e2: FromModel) -> None: 34 if e1.elemental is not e2.elemental: 35 raise ValueError( 36 f"Expected two elements from the same model, but observed {e1} from" 37 f" model named: '{e1.elemental.model_name!r}', and {e2} from model" 38 f" named: '{e2.elemental.model_name!r}'." 39 )