Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/tensorflow/python/autograph/operators/variables.py: 44%
27 statements
« prev ^ index » next coverage.py v7.4.0, created at 2024-01-03 07:57 +0000
« prev ^ index » next coverage.py v7.4.0, created at 2024-01-03 07:57 +0000
1# Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2#
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 used to capture Python idioms."""
18def ld(v):
19 """Load variable operator."""
20 if isinstance(v, Undefined):
21 return v.read()
22 return v
25def ldu(load_v, name):
26 """Load variable operator that returns Undefined when failing to evaluate.
28 Note: the name ("load or return undefined") is abbreviated to minimize
29 the amount of clutter in generated code.
31 This variant of `ld` is useful when loading symbols that may be undefined at
32 runtime, such as composite symbols, and whether they are defined or not cannot
33 be determined statically. For example `d['a']` is undefined when `d` is an
34 empty dict.
36 Args:
37 load_v: Lambda that executes the actual read.
38 name: Human-readable name of the symbol being read.
39 Returns:
40 Either the value of the symbol, or Undefined, if the symbol is not fully
41 defined.
42 """
43 try:
44 # TODO(mdan): Use locals()/globals() here.
45 return load_v()
46 except (KeyError, AttributeError, NameError):
47 return Undefined(name)
50class Undefined(object):
51 """Represents an undefined symbol in Python.
53 This is used to reify undefined symbols, which is required to use the
54 functional form of loops.
55 Example:
57 while n > 0:
58 n = n - 1
59 s = n
60 return s # Runtime error if n == 0
62 This is valid Python code and will not result in an error as long as n
63 is positive. The use of this class is to stay as close to Python semantics
64 as possible for staged code of this nature.
66 Converted version of the above showing the possible usage of this class:
68 s = Undefined('s')
69 init_state = (s,)
70 s = while_loop(cond, body, init_state)
71 return s # s is an instance of Undefined if the loop never runs
73 Attributes:
74 symbol_name: Text, identifier for the undefined symbol
75 """
77 __slots__ = ('symbol_name',)
79 def __init__(self, symbol_name):
80 self.symbol_name = symbol_name
82 def read(self):
83 raise UnboundLocalError("'{}' is used before assignment".format(
84 self.symbol_name))
86 def __repr__(self):
87 return self.symbol_name
89 def __getattribute__(self, name):
90 try:
91 # If it's an existing attribute, return it.
92 return object.__getattribute__(self, name)
93 except AttributeError:
94 # Otherwise return Undefined.
95 return self
97 def __getitem__(self, i):
98 return self
101# TODO(mdan): Refactor as a RetVal object, aggregating the value and do_return.
102class UndefinedReturnValue(object):
103 """Represents a return value that is undefined."""
104 pass