# Copyright 2018 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import copy
import os

import numpy
import six

from tensorflow.python.eager import context
from tensorflow.python.eager import test
from tensorflow.python.framework import constant_op
from tensorflow.python.framework import test_util
from tensorflow.python.keras.engine import training
from tensorflow.python.keras.layers import core
from tensorflow.python.keras.layers import normalization
from tensorflow.python.layers import core as non_keras_core
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import math_ops
from tensorflow.python.ops import resource_variable_ops
from tensorflow.python.ops import variables
from tensorflow.python.training.tracking import data_structures
from tensorflow.python.training.tracking import tracking
from tensorflow.python.training.tracking import util


class HasList(training.Model):

  def __init__(self):
    super(HasList, self).__init__()
    self.layer_list = data_structures.List([core.Dense(3)])
    self.layer_list.append(core.Dense(4))
    self.layer_list.extend(
        [core.Dense(5),
         core.Dense(6, kernel_regularizer=math_ops.reduce_sum)])
    self.layer_list += [
        core.Dense(7, bias_regularizer=math_ops.reduce_sum),
        core.Dense(8)
    ]
    self.layer_list += (
        data_structures.List([core.Dense(9)]) + data_structures.List(
            [core.Dense(10)]))
    self.layer_list.extend(
        data_structures.List(
            list([core.Dense(11)]) + [core.Dense(12)]))
    self.layers_with_updates = data_structures.List(
        (normalization.BatchNormalization(),))

  def call(self, x):
    aggregation = 0.
    for l in self.layer_list:
      x = l(x)
      aggregation += math_ops.reduce_sum(x)
    bn, = self.layers_with_updates
    return bn(x) / aggregation


class ListTests(test.TestCase):

  @test_util.run_in_graph_and_eager_modes
  @test_util.run_v1_only("b/120545219")
  def testTracking(self):
    model = HasList()
    output = model(array_ops.ones([32, 2]))
    self.assertAllEqual([32, 12], output.shape)
    self.assertEqual(11, len(model.layers))
    self.assertEqual(10, len(model.layer_list.layers))
    six.assertCountEqual(
        self,
        model.layers,
        model.layer_list.layers + model.layers_with_updates)
    for index in range(10):
      self.assertEqual(3 + index, model.layer_list.layers[index].units)
    self.assertEqual(2, len(model._checkpoint_dependencies))
    self.assertIs(model.layer_list, model._checkpoint_dependencies[0].ref)
    self.assertIs(model.layers_with_updates,
                  model._checkpoint_dependencies[1].ref)
    self.assertEqual(
        10, len(model._checkpoint_dependencies[0].ref._checkpoint_dependencies))
    self.evaluate([v.initializer for v in model.variables])
    self.evaluate(model.variables[0].assign([[1., 2., 3.], [4., 5., 6.]]))
    save_path = os.path.join(self.get_temp_dir(), "ckpt")
    model.save_weights(save_path)
    self.evaluate(model.variables[0].assign(array_ops.zeros([2, 3])))
    model.load_weights(save_path)
    self.assertAllEqual([[1., 2., 3.], [4., 5., 6.]],
                        self.evaluate(model.variables[0]))
    v = variables.Variable(1.)
    model.var_list = [v]
    self.assertIn(v, model.variables)
    self.assertIn(v, model.trainable_variables)
    self.assertNotIn(v, model.non_trainable_variables)

  @test_util.run_v1_only("b/120545219")
  def testUpdatesForwarded(self):
    with context.graph_mode():
      model = HasList()
      model_input = array_ops.ones([32, 2])
      model(model_input)
      self.assertGreater(len(model.layers_with_updates[0].updates), 0)
      self.assertEqual(set(model.layers_with_updates[0].updates),
                       set(model.updates))

    with context.eager_mode():
      model = HasList()
      model_input = array_ops.ones([32, 2])
      model(model_input)
      self.assertEqual(0, len(model.updates))

  @test_util.run_in_graph_and_eager_modes
  @test_util.run_v1_only("b/120545219")
  def testLossesForwarded(self):
    model = HasList()
    model_input = array_ops.ones([32, 2])
    model(model_input)
    self.assertEqual(2, len(model.losses))

  def testModelContainersCompareEqual(self):
    class HasEqualContainers(training.Model):

      def __init__(self):
        super(HasEqualContainers, self).__init__()
        self.l1 = []
        self.l2 = []

    model = HasEqualContainers()
    first_layer = HasEqualContainers()
    model.l1.append(first_layer)
    second_layer = HasEqualContainers()
    model.l2.append(second_layer)
    self.assertEqual([first_layer, second_layer], model.layers)

  def testNotTrackable(self):
    class NotTrackable(object):
      pass

    with self.assertRaises(ValueError):
      data_structures.List([NotTrackable()])

  def testCallNotImplemented(self):
    with self.assertRaisesRegexp(TypeError, "not callable"):
      data_structures.List()(1.)

  def testNoPop(self):
    with self.assertRaises(AttributeError):
      data_structures.List().pop()

  @test_util.run_in_graph_and_eager_modes
  def testTensorConversion(self):

    class ListToTensor(training.Model):

      def __init__(self):
        super(ListToTensor, self).__init__()
        self.l = [1., 2., 3.]

    self.assertAllEqual(
        [1., 2., 3.],
        self.evaluate(constant_op.constant(ListToTensor().l)))

    self.assertAllEqual(
        [1., 2., 3.],
        self.evaluate(array_ops.pack(ListToTensor().l)))

  def testNesting(self):
    with context.graph_mode():
      inner = data_structures.List()
      outer = data_structures.List([inner])
      inner.append(non_keras_core.Dense(1))
      inner[0](array_ops.ones([2, 3]))
      self.assertEqual(2, len(outer.variables))
      self.assertIsInstance(
          outer.variables[0],
          resource_variable_ops.ResourceVariable)

  def testNonLayerVariables(self):
    v = resource_variable_ops.ResourceVariable([1.])
    l = data_structures.List([v])
    self.assertTrue(l.trainable)
    self.assertEqual([], l.layers)
    self.assertEqual([v], l.variables)
    self.assertEqual([v], l.trainable_weights)
    self.assertEqual([], l.non_trainable_variables)
    l.trainable = False
    self.assertEqual([v], l.variables)
    self.assertEqual([], l.trainable_variables)
    self.assertEqual([v], l.non_trainable_variables)
    l.trainable = True
    v2 = resource_variable_ops.ResourceVariable(1., trainable=False)
    l.append(v2)
    self.assertEqual([v, v2], l.weights)
    self.assertEqual([v], l.trainable_weights)
    self.assertEqual([v2], l.non_trainable_weights)

  def testCopy(self):
    v1 = resource_variable_ops.ResourceVariable(1.)
    v2 = resource_variable_ops.ResourceVariable(1.)
    v3 = resource_variable_ops.ResourceVariable(1.)

    l1 = data_structures.List([v1, v2])
    l2 = l1.copy()
    l2.append(v3)
    self.assertEqual(list(l1), [v1, v2])
    self.assertEqual(list(l2), [v1, v2, v3])

  def testSlicing(self):
    v1 = resource_variable_ops.ResourceVariable(1.)
    v2 = resource_variable_ops.ResourceVariable(1.)
    v3 = resource_variable_ops.ResourceVariable(1.)
    v4 = resource_variable_ops.ResourceVariable(1.)

    l = data_structures.List([v1, v2, v3, v4])
    self.assertEqual(l[1:], [v2, v3, v4])
    self.assertEqual(l[1:-1], [v2, v3])
    self.assertEqual(l[:-1], [v1, v2, v3])

  def testHash(self):
    has_sequences = set([data_structures.List(),
                         data_structures.List()])
    self.assertEqual(2, len(has_sequences))
    self.assertNotIn(data_structures.List(), has_sequences)

  def testIMul_zero(self):
    l = data_structures.List([])
    with self.assertRaisesRegexp(ValueError, "List only supports append"):
      l *= 0

  def testIMul(self):
    v = resource_variable_ops.ResourceVariable(1.)
    l = data_structures.List([v])
    l *= 2
    self.assertEqual(list(l), [v] * 2)

  def testMul(self):
    v = resource_variable_ops.ResourceVariable(1.)
    l = data_structures.List([v, v, v])
    self.assertEqual(list(l * 2), [v, v, v] * 2)

  def testRMul(self):
    v = resource_variable_ops.ResourceVariable(1.)
    l = data_structures.List([v, v, v])
    self.assertEqual(list(2 * l), [v, v, v] * 2)


class ListWrapperTest(test.TestCase):

  IGNORED = ("__new__", "__init__", "__subclasshook__", "__getattribute__")

  def test_overrides_all_list_methods(self):
    not_overridden = []

    for name in dir(list):
      if name in ListWrapperTest.IGNORED:
        continue

      list_method = getattr(list, name)

      if not callable(list_method):
        continue

      object_method = getattr(object, name, None)
      if object_method is not None and object_method == list_method:
        # Skip methods that aren't overridden from object.
        continue

      if list_method == getattr(data_structures._ListWrapper, name):
        not_overridden.append(name)

    if not_overridden:
      self.fail("_ListWrapper does not override %s" % (not_overridden))

  def testListWrapperBasic(self):
    # _ListWrapper, unlike List, compares like the built-in list type (since it
    # is used to automatically replace lists).
    a = tracking.AutoTrackable()
    b = tracking.AutoTrackable()
    self.assertEqual([a, a],
                     [a, a])
    self.assertEqual(data_structures._ListWrapper([a, a]),
                     data_structures._ListWrapper([a, a]))
    self.assertEqual([a, a],
                     data_structures._ListWrapper([a, a]))
    self.assertEqual(data_structures._ListWrapper([a, a]),
                     [a, a])
    self.assertNotEqual([a, a],
                        [b, a])
    self.assertNotEqual(data_structures._ListWrapper([a, a]),
                        data_structures._ListWrapper([b, a]))
    self.assertNotEqual([a, a],
                        data_structures._ListWrapper([b, a]))
    self.assertLess([a], [a, b])
    self.assertLess(data_structures._ListWrapper([a]),
                    data_structures._ListWrapper([a, b]))
    self.assertLessEqual([a], [a, b])
    self.assertLessEqual(data_structures._ListWrapper([a]),
                         data_structures._ListWrapper([a, b]))
    self.assertGreater([a, b], [a])
    self.assertGreater(data_structures._ListWrapper([a, b]),
                       data_structures._ListWrapper([a]))
    self.assertGreaterEqual([a, b], [a])
    self.assertGreaterEqual(data_structures._ListWrapper([a, b]),
                            data_structures._ListWrapper([a]))
    self.assertEqual([a], data_structures._ListWrapper([a]))
    self.assertEqual([a], list(data_structures.List([a])))
    self.assertEqual([a, a], data_structures._ListWrapper([a]) + [a])
    self.assertEqual([a, a], [a] + data_structures._ListWrapper([a]))
    self.assertIsInstance(data_structures._ListWrapper([a]), list)

  def testAcceptsNonTrackableContent(self):
    l = data_structures._ListWrapper([1, 2, 3])
    self.assertEqual(l, [1, 2, 3])

  def testWrapperChangesList(self):
    l = []
    l_wrapper = data_structures._ListWrapper(l)
    l_wrapper.append(1)
    self.assertEqual([1], l)

  def testListChangesWrapper(self):
    l = []
    l_wrapper = data_structures._ListWrapper(l)
    l.append(1)
    self.assertEqual([1], l_wrapper)

  def testLayerCollectionWithExternalMutation(self):
    l = []
    l_wrapper = data_structures._ListWrapper(l)
    layer = core.Dense(1)
    l.append(layer)
    self.assertEqual([layer], l_wrapper.layers)

  def testNotHashable(self):
    with self.assertRaises(TypeError):
      hash(data_structures._ListWrapper())

  def testDelItem(self):
    l = data_structures._ListWrapper([1, 2, 3, 4])
    del l[0]
    self.assertEqual(l, [2, 3, 4])
    self.assertUnableToSave(l, "Unable to save .*__delitem__")

  def testDelSlice(self):
    l = data_structures._ListWrapper([1, 2, 3, 4])
    del l[2:3]
    self.assertEqual(l, [1, 2, 4])
    self.assertUnableToSave(l, "Unable to save .*__delslice__")

  def testSetSlice_canSaveForNonTrackableItems(self):
    l = data_structures._ListWrapper([1, 2, 3, 4])
    l[:] = 2, 8, 9, 0
    self.assertEqual(l, [2, 8, 9, 0])
    l._maybe_initialize_trackable()  # pylint: disable=protected-access
    self.assertEqual(len(l._checkpoint_dependencies), 0)  # pylint: disable=protected-access

  def testSetSlice_cannotSaveIfTrackableModified(self):
    v1 = resource_variable_ops.ResourceVariable(1.)
    v2 = resource_variable_ops.ResourceVariable(1.)
    l = data_structures._ListWrapper([1, 2, v1, v2])
    l[:] = 2, 8, 9, v2
    self.assertEqual(l, [2, 8, 9, v2])
    self.assertUnableToSave(l, "Unable to save .*__setslice__")

  def testSetSlice_truncate(self):
    l = data_structures._ListWrapper([1, 2, 3, 4])
    l[:] = []
    self.assertEqual(l, [])

  def testSetSlice_extend(self):
    l = data_structures._ListWrapper([1, 2, 3, 4])
    l[2:] = 1, 2, 3, 4
    self.assertEqual(l, [1, 2, 1, 2, 3, 4])

  def testIMulNegative(self):
    l = data_structures._ListWrapper([1, 2, 3, 4])
    l *= -1
    self.assertEqual(l, [1, 2, 3, 4] * -1)
    self.assertUnableToSave(l, "Unable to save")

  def testIMulPositive(self):
    v = variables.Variable(1.)
    l = data_structures._ListWrapper([1, 2, 3, 4, v])
    self.assertEqual([("4", v)], l._checkpoint_dependencies)
    root = util.Checkpoint(l=l)
    prefix = os.path.join(self.get_temp_dir(), "ckpt")
    path = root.save(prefix)
    v.assign(5.)
    l *= 2
    self.assertEqual(l, [1, 2, 3, 4, v, 1, 2, 3, 4, v])
    self.assertEqual([("4", v), ("9", v)], l._checkpoint_dependencies)
    root.restore(path)
    self.assertAllClose(1., v.numpy())

  def testSort(self):
    l = data_structures._ListWrapper([1, 2, 3, 4])
    l.sort()
    self.assertEqual(l, [1, 2, 3, 4])
    # Regardless of being a no-op for the input list, we still refuse to save.
    # This is intentional since otherwise we would end up with a hard to debug
    # case for users (e.g. sometimes sort on a ListWrapper is trackable and
    # other times it is not).
    self.assertUnableToSave(l, "Unable to save .*sort")

  def assertUnableToSave(self, l, msg):
    l._maybe_initialize_trackable()  # pylint: disable=protected-access
    with self.assertRaisesRegexp(ValueError, msg):
      return l._checkpoint_dependencies  # pylint: disable=protected-access


class HasMapping(training.Model):

  def __init__(self):
    super(HasMapping, self).__init__()
    self.layer_dict = data_structures.Mapping(output=core.Dense(7))
    self.layer_dict["norm"] = data_structures.List()
    self.layer_dict["dense"] = data_structures.List()
    self.layer_dict["dense"].extend(
        [core.Dense(5),
         core.Dense(6, kernel_regularizer=math_ops.reduce_sum)])
    self.layer_dict["norm"].append(
        normalization.BatchNormalization())
    self.layer_dict["norm"].append(
        normalization.BatchNormalization())

  def call(self, x):
    aggregation = 0.
    for norm, dense in zip(self.layer_dict["norm"], self.layer_dict["dense"]):
      x = norm(dense(x))
      aggregation += math_ops.reduce_sum(x)
    return self.layer_dict["output"](x) / aggregation


class MappingTests(test.TestCase):

  @test_util.run_in_graph_and_eager_modes
  @test_util.run_v1_only("b/120545219")
  def testTracking(self):
    model = HasMapping()
    output = model(array_ops.ones([32, 2]))
    self.assertAllEqual([32, 7], output.shape)
    self.assertEqual(5, len(model.layers))
    six.assertCountEqual(self, model.layers, model.layer_dict.layers)
    self.assertEqual(1, len(model._checkpoint_dependencies))
    self.assertIs(model.layer_dict, model._checkpoint_dependencies[0].ref)
    self.evaluate([v.initializer for v in model.variables])
    test_var = model.layer_dict["output"].kernel
    self.evaluate(test_var.assign(array_ops.ones([6, 7])))
    save_path = os.path.join(self.get_temp_dir(), "ckpt")
    model.save_weights(save_path)
    self.evaluate(test_var.assign(array_ops.zeros([6, 7])))
    model.load_weights(save_path)
    self.assertAllEqual(numpy.ones([6, 7]),
                        self.evaluate(test_var))

  def testNoOverwrite(self):
    mapping = data_structures.Mapping()
    original = data_structures.List()
    mapping["a"] = original
    with self.assertRaises(ValueError):
      mapping["a"] = data_structures.List()
    self.assertIs(original, mapping["a"])
    with self.assertRaises(AttributeError):
      del mapping["a"]
    mapping.update(b=data_structures.Mapping())
    with self.assertRaises(ValueError):
      mapping.update({"b": data_structures.Mapping()})

  def testNonStringKeys(self):
    mapping = data_structures.Mapping()
    with self.assertRaises(TypeError):
      mapping[1] = data_structures.List()

  def testLayerCollectionWithExternalMutation(self):
    d = {}
    root = tracking.AutoTrackable()
    root.wrapper = d
    self.assertEqual([], root.wrapper.layers)
    self.assertEqual([], root.wrapper.trainable_weights)
    layer1 = core.Dense(1)
    layer2 = core.Dense(1)
    d["a"] = layer1
    d["b"] = layer2
    self.assertEqual([layer1, layer2], root.wrapper.layers)
    # The layers have still not created variables
    self.assertEqual([], root.wrapper.trainable_weights)

  def testHashing(self):
    has_mappings = set([data_structures.Mapping(),
                        data_structures.Mapping()])
    self.assertEqual(2, len(has_mappings))
    self.assertNotIn(data_structures.Mapping(), has_mappings)
    # In contrast to Mapping, dict wrappers are not hashable
    a = tracking.AutoTrackable()
    a.d = {}
    self.assertEqual({}, a.d)
    self.assertFalse({} != a.d)  # pylint: disable=g-explicit-bool-comparison
    self.assertNotEqual({1: 2}, a.d)
    with self.assertRaisesRegexp(TypeError, "unhashable"):
      set([a.d])

  def testDictWrapperBadKeys(self):
    a = tracking.AutoTrackable()
    a.d = {}
    a.d[1] = data_structures.List()
    model = training.Model()
    model.sub = a
    save_path = os.path.join(self.get_temp_dir(), "ckpt")
    with self.assertRaisesRegexp(ValueError, "non-string key"):
      model.save_weights(save_path)

  def testDictWrapperNoDependency(self):
    a = tracking.AutoTrackable()
    a.d = data_structures.NoDependency({})
    a.d[1] = [3]
    self.assertEqual([a], util.list_objects(a))
    model = training.Model()
    model.sub = a
    save_path = os.path.join(self.get_temp_dir(), "ckpt")
    model.save_weights(save_path)
    model.load_weights(save_path)

  def testNonStringKeyNotTrackableValue(self):
    a = tracking.AutoTrackable()
    a.d = {}
    a.d["a"] = [3]
    a.d[1] = data_structures.NoDependency([3])
    self.assertEqual([a, a.d, a.d["a"]], util.list_objects(a))
    model = training.Model()
    model.sub = a
    save_path = os.path.join(self.get_temp_dir(), "ckpt")
    model.save_weights(save_path)
    model.load_weights(save_path)

  def testNonAppendNotTrackable(self):
    # Non-append mutations (deleting or overwriting values) are OK when the
    # values aren't tracked.
    a = tracking.AutoTrackable()
    a.d = {}
    a.d["a"] = [3]
    a.d[1] = 3
    a.d[1] = 2
    self.assertEqual(2, a.d[1])
    del a.d[1]
    a.d[2] = data_structures.NoDependency(tracking.AutoTrackable())
    second = tracking.AutoTrackable()
    a.d[2] = data_structures.NoDependency(second)
    self.assertIs(second, a.d[2])
    self.assertEqual([a, a.d, a.d["a"]], util.list_objects(a))
    model = training.Model()
    model.sub = a
    save_path = os.path.join(self.get_temp_dir(), "ckpt")
    model.save_weights(save_path)
    model.load_weights(save_path)

  def testDelNoSave(self):
    model = training.Model()
    model.d = {}
    model.d["a"] = []
    del model.d["a"]
    save_path = os.path.join(self.get_temp_dir(), "ckpt")
    with self.assertRaisesRegexp(ValueError, "overwritten or deleted"):
      model.save_weights(save_path)

  def testPopNoSave(self):
    model = training.Model()
    model.d = {}
    model.d["a"] = []
    model.d.pop("a")
    save_path = os.path.join(self.get_temp_dir(), "ckpt")
    with self.assertRaisesRegexp(ValueError, "overwritten or deleted"):
      model.save_weights(save_path)

  def testExternalModificationNoSave(self):
    model = training.Model()
    external_reference = {}
    model.d = external_reference
    external_reference["a"] = []
    save_path = os.path.join(self.get_temp_dir(), "ckpt")
    with self.assertRaisesRegexp(ValueError, "modified outside the wrapper"):
      model.save_weights(save_path)

  def testOverwriteNoSave(self):
    model = training.Model()
    model.d = {}
    model.d["a"] = {}
    model.d["a"] = {}
    save_path = os.path.join(self.get_temp_dir(), "ckpt")
    with self.assertRaisesRegexp(ValueError, "overwritten or deleted"):
      model.save_weights(save_path)

  def testIter(self):
    model = training.Model()
    model.d = {1: 3}
    model.d[1] = 3
    self.assertEqual([1], list(model.d))
    new_dict = {}
    # This update() is super tricky. If the dict wrapper subclasses dict,
    # CPython will access its storage directly instead of calling any
    # methods/properties on the object. So the options are either not to
    # subclass dict (in which case update will call normal iter methods, but the
    # object won't pass isinstance checks) or to subclass dict and keep that
    # storage updated (no shadowing all its methods like _ListWrapper).
    new_dict.update(model.d)
    self.assertEqual({1: 3}, new_dict)

  def testListShallowCopy(self):
    root = tracking.AutoTrackable()
    orig_list = [[1.]]
    root.a = orig_list
    copied = copy.copy(root.a)
    self.assertAllEqual([[1.]], copied)
    self.assertIsNot(root.a, copied)
    self.assertIs(root.a[0], copied[0])

    # Dirtiness should be inherited
    util.list_objects(root.a)
    orig_list.append(1.)
    with self.assertRaises(ValueError):
      util.list_objects(root.a)
    with self.assertRaises(ValueError):
      util.list_objects(copy.copy(root.a))

  def testListDeepCopy(self):
    root = tracking.AutoTrackable()
    orig_list = [[1.]]
    root.a = orig_list
    copied = copy.deepcopy(root.a)
    self.assertAllEqual([[1.]], copied)
    self.assertIsNot(root.a, copied)
    self.assertIsNot(root.a[0], copied[0])

    # Dirtiness should be inherited
    util.list_objects(root.a)
    orig_list.append(1.)
    with self.assertRaises(ValueError):
      util.list_objects(root.a)
    with self.assertRaises(ValueError):
      util.list_objects(copy.deepcopy(root.a))

  def testDictShallowCopy(self):
    root = tracking.AutoTrackable()
    orig_dict = {"a": [1.]}
    root.a = orig_dict
    copied = copy.copy(root.a)
    self.assertAllEqual([1.], copied["a"])
    self.assertIsNot(root.a, copied)
    self.assertIs(root.a["a"], copied["a"])

    copied = root.a.copy()
    self.assertAllEqual([1.], copied["a"])
    self.assertIsNot(root.a, copied)
    self.assertIs(root.a["a"], copied["a"])

    # Dirtiness should be inherited
    util.list_objects(root.a)
    orig_dict["b"] = []
    with self.assertRaises(ValueError):
      util.list_objects(root.a)
    with self.assertRaises(ValueError):
      util.list_objects(copy.copy(root.a))

  def testDictDeepCopy(self):
    root = tracking.AutoTrackable()
    orig_dict = {"a": [1.]}
    root.a = orig_dict
    copied = copy.deepcopy(root.a)
    self.assertAllEqual([1.], copied["a"])
    self.assertIsNot(root.a, copied)
    self.assertIsNot(root.a["a"], copied["a"])

    # Dirtiness should be inherited
    util.list_objects(root.a)
    orig_dict["b"] = []
    with self.assertRaises(ValueError):
      util.list_objects(root.a)
    with self.assertRaises(ValueError):
      util.list_objects(copy.deepcopy(root.a))

  def testShallowCopyTrackable(self):
    original = tracking.AutoTrackable()
    original_sub = tracking.AutoTrackable()
    original.a = [[1.]]
    original.b = {"a": original_sub}
    shallow_copied = copy.copy(original)
    self.assertIs(original_sub, shallow_copied.b["a"])
    self.assertIsNot(original, shallow_copied)
    self.assertEqual([[1.]], shallow_copied.a)
    shallow_deps = util.list_objects(shallow_copied)
    self.assertIn(shallow_copied.a, shallow_deps)
    self.assertIn(shallow_copied.b, shallow_deps)
    self.assertIn(shallow_copied.b["a"], shallow_deps)

  def testDeepCopyTrackable(self):
    original = tracking.AutoTrackable()
    original_sub = tracking.AutoTrackable()
    original.a = [[1.]]
    original.b = {"a": original_sub}
    deep_copied = copy.deepcopy(original)
    self.assertIsNot(original, deep_copied)
    self.assertIsNot(original_sub, deep_copied.b["a"])
    self.assertEqual([[1.]], deep_copied.a)
    self.assertIsInstance(deep_copied.b["a"], tracking.AutoTrackable)
    deps = util.list_objects(deep_copied)
    self.assertIn(deep_copied.a, deps)
    self.assertIn(deep_copied.b, deps)
    self.assertIn(deep_copied.b["a"], deps)
    self.assertNotIn(original_sub, deps)

  def testConstructableFromSequence(self):
    result = data_structures._DictWrapper([(1, 2), (3, 4)])
    self.assertIsInstance(result, dict)
    self.assertEqual({1: 2, 3: 4}, result)

  def testListAddOrder(self):
    self.assertEqual([1., 2.],
                     data_structures._ListWrapper([1.])
                     + data_structures._ListWrapper([2.]))
    self.assertEqual([1., 2.],
                     data_structures._ListWrapper([1.])
                     + [2.])
    self.assertEqual([1., 2.],
                     [1.]
                     + data_structures._ListWrapper([2.]))


if __name__ == "__main__":
  test.main()

tensorflow.python.training.tracking.util.list_objects tensorflow.python.keras.layers.normalization.BatchNormalization tensorflow.python.ops.variables.Variable tensorflow.python.ops.array_ops.zeros tensorflow.python.layers.core.Dense tensorflow.python.framework.test_util.run_v1_only tensorflow.python.ops.resource_variable_ops.ResourceVariable tensorflow.python.training.tracking.data_structures._DictWrapper tensorflow.python.ops.array_ops.ones tensorflow.python.training.tracking.data_structures._ListWrapper tensorflow.python.eager.context.graph_mode tensorflow.python.eager.context.eager_mode tensorflow.python.eager.test.main tensorflow.python.training.tracking.tracking.AutoTrackable tensorflow.python.training.tracking.data_structures.NoDependency tensorflow.python.keras.layers.core.Dense tensorflow.python.training.tracking.data_structures.Mapping tensorflow.python.training.tracking.data_structures.List numpy.ones tensorflow.python.training.tracking.util.Checkpoint tensorflow.python.ops.math_ops.reduce_sum tensorflow.python.keras.engine.training.Model
[(76, 'tensorflow.python.framework.test_util.run_v1_only', 'test_util.run_v1_only', (['"""b/120545219"""'], {}), False, 'from tensorflow.python.framework import test_util\n'), (109, 'tensorflow.python.framework.test_util.run_v1_only', 'test_util.run_v1_only', (['"""b/120545219"""'], {}), False, 'from tensorflow.python.framework import test_util\n'), (126, 'tensorflow.python.framework.test_util.run_v1_only', 'test_util.run_v1_only', (['"""b/120545219"""'], {}), False, 'from tensorflow.python.framework import test_util\n'), (450, 'tensorflow.python.framework.test_util.run_v1_only', 'test_util.run_v1_only', (['"""b/120545219"""'], {}), False, 'from tensorflow.python.framework import test_util\n'), (741, 'tensorflow.python.eager.test.main', 'test.main', ([], {}), False, 'from tensorflow.python.eager import test\n'), (83, 'six.assertCountEqual', 'six.assertCountEqual', (['self', 'model.layers', '(model.layer_list.layers + model.layers_with_updates)'], {}), False, 'import six\n'), (103, 'tensorflow.python.ops.variables.Variable', 'variables.Variable', (['(1.0)'], {}), False, 'from tensorflow.python.ops import variables\n'), (129, 'tensorflow.python.ops.array_ops.ones', 'array_ops.ones', (['[32, 2]'], {}), False, 'from tensorflow.python.ops import array_ops\n'), (192, 'tensorflow.python.ops.resource_variable_ops.ResourceVariable', 'resource_variable_ops.ResourceVariable', (['[1.0]'], {}), False, 'from tensorflow.python.ops import resource_variable_ops\n'), (193, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', (['[v]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (204, 'tensorflow.python.ops.resource_variable_ops.ResourceVariable', 'resource_variable_ops.ResourceVariable', (['(1.0)'], {'trainable': '(False)'}), False, 'from tensorflow.python.ops import resource_variable_ops\n'), (211, 'tensorflow.python.ops.resource_variable_ops.ResourceVariable', 'resource_variable_ops.ResourceVariable', (['(1.0)'], {}), False, 'from tensorflow.python.ops import resource_variable_ops\n'), (212, 'tensorflow.python.ops.resource_variable_ops.ResourceVariable', 'resource_variable_ops.ResourceVariable', (['(1.0)'], {}), False, 'from tensorflow.python.ops import resource_variable_ops\n'), (213, 'tensorflow.python.ops.resource_variable_ops.ResourceVariable', 'resource_variable_ops.ResourceVariable', (['(1.0)'], {}), False, 'from tensorflow.python.ops import resource_variable_ops\n'), (215, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', (['[v1, v2]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (222, 'tensorflow.python.ops.resource_variable_ops.ResourceVariable', 'resource_variable_ops.ResourceVariable', (['(1.0)'], {}), False, 'from tensorflow.python.ops import resource_variable_ops\n'), (223, 'tensorflow.python.ops.resource_variable_ops.ResourceVariable', 'resource_variable_ops.ResourceVariable', (['(1.0)'], {}), False, 'from tensorflow.python.ops import resource_variable_ops\n'), (224, 'tensorflow.python.ops.resource_variable_ops.ResourceVariable', 'resource_variable_ops.ResourceVariable', (['(1.0)'], {}), False, 'from tensorflow.python.ops import resource_variable_ops\n'), (225, 'tensorflow.python.ops.resource_variable_ops.ResourceVariable', 'resource_variable_ops.ResourceVariable', (['(1.0)'], {}), False, 'from tensorflow.python.ops import resource_variable_ops\n'), (227, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', (['[v1, v2, v3, v4]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (239, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', (['[]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (244, 'tensorflow.python.ops.resource_variable_ops.ResourceVariable', 'resource_variable_ops.ResourceVariable', (['(1.0)'], {}), False, 'from tensorflow.python.ops import resource_variable_ops\n'), (245, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', (['[v]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (250, 'tensorflow.python.ops.resource_variable_ops.ResourceVariable', 'resource_variable_ops.ResourceVariable', (['(1.0)'], {}), False, 'from tensorflow.python.ops import resource_variable_ops\n'), (251, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', (['[v, v, v]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (255, 'tensorflow.python.ops.resource_variable_ops.ResourceVariable', 'resource_variable_ops.ResourceVariable', (['(1.0)'], {}), False, 'from tensorflow.python.ops import resource_variable_ops\n'), (256, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', (['[v, v, v]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (290, 'tensorflow.python.training.tracking.tracking.AutoTrackable', 'tracking.AutoTrackable', ([], {}), False, 'from tensorflow.python.training.tracking import tracking\n'), (291, 'tensorflow.python.training.tracking.tracking.AutoTrackable', 'tracking.AutoTrackable', ([], {}), False, 'from tensorflow.python.training.tracking import tracking\n'), (325, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[1, 2, 3]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (330, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['l'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (336, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['l'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (342, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['l'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (343, 'tensorflow.python.keras.layers.core.Dense', 'core.Dense', (['(1)'], {}), False, 'from tensorflow.python.keras.layers import core\n'), (352, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[1, 2, 3, 4]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (358, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[1, 2, 3, 4]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (364, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[1, 2, 3, 4]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (371, 'tensorflow.python.ops.resource_variable_ops.ResourceVariable', 'resource_variable_ops.ResourceVariable', (['(1.0)'], {}), False, 'from tensorflow.python.ops import resource_variable_ops\n'), (372, 'tensorflow.python.ops.resource_variable_ops.ResourceVariable', 'resource_variable_ops.ResourceVariable', (['(1.0)'], {}), False, 'from tensorflow.python.ops import resource_variable_ops\n'), (373, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[1, 2, v1, v2]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (379, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[1, 2, 3, 4]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (384, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[1, 2, 3, 4]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (389, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[1, 2, 3, 4]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (395, 'tensorflow.python.ops.variables.Variable', 'variables.Variable', (['(1.0)'], {}), False, 'from tensorflow.python.ops import variables\n'), (396, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[1, 2, 3, 4, v]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (398, 'tensorflow.python.training.tracking.util.Checkpoint', 'util.Checkpoint', ([], {'l': 'l'}), False, 'from tensorflow.python.training.tracking import util\n'), (409, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[1, 2, 3, 4]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (429, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (430, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (456, 'six.assertCountEqual', 'six.assertCountEqual', (['self', 'model.layers', 'model.layer_dict.layers'], {}), False, 'import six\n'), (470, 'tensorflow.python.training.tracking.data_structures.Mapping', 'data_structures.Mapping', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (471, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (483, 'tensorflow.python.training.tracking.data_structures.Mapping', 'data_structures.Mapping', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (489, 'tensorflow.python.training.tracking.tracking.AutoTrackable', 'tracking.AutoTrackable', ([], {}), False, 'from tensorflow.python.training.tracking import tracking\n'), (493, 'tensorflow.python.keras.layers.core.Dense', 'core.Dense', (['(1)'], {}), False, 'from tensorflow.python.keras.layers import core\n'), (494, 'tensorflow.python.keras.layers.core.Dense', 'core.Dense', (['(1)'], {}), False, 'from tensorflow.python.keras.layers import core\n'), (507, 'tensorflow.python.training.tracking.tracking.AutoTrackable', 'tracking.AutoTrackable', ([], {}), False, 'from tensorflow.python.training.tracking import tracking\n'), (516, 'tensorflow.python.training.tracking.tracking.AutoTrackable', 'tracking.AutoTrackable', ([], {}), False, 'from tensorflow.python.training.tracking import tracking\n'), (518, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (519, 'tensorflow.python.keras.engine.training.Model', 'training.Model', ([], {}), False, 'from tensorflow.python.keras.engine import training\n'), (526, 'tensorflow.python.training.tracking.tracking.AutoTrackable', 'tracking.AutoTrackable', ([], {}), False, 'from tensorflow.python.training.tracking import tracking\n'), (527, 'tensorflow.python.training.tracking.data_structures.NoDependency', 'data_structures.NoDependency', (['{}'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (530, 'tensorflow.python.keras.engine.training.Model', 'training.Model', ([], {}), False, 'from tensorflow.python.keras.engine import training\n'), (537, 'tensorflow.python.training.tracking.tracking.AutoTrackable', 'tracking.AutoTrackable', ([], {}), False, 'from tensorflow.python.training.tracking import tracking\n'), (540, 'tensorflow.python.training.tracking.data_structures.NoDependency', 'data_structures.NoDependency', (['[3]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (542, 'tensorflow.python.keras.engine.training.Model', 'training.Model', ([], {}), False, 'from tensorflow.python.keras.engine import training\n'), (551, 'tensorflow.python.training.tracking.tracking.AutoTrackable', 'tracking.AutoTrackable', ([], {}), False, 'from tensorflow.python.training.tracking import tracking\n'), (559, 'tensorflow.python.training.tracking.tracking.AutoTrackable', 'tracking.AutoTrackable', ([], {}), False, 'from tensorflow.python.training.tracking import tracking\n'), (560, 'tensorflow.python.training.tracking.data_structures.NoDependency', 'data_structures.NoDependency', (['second'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (563, 'tensorflow.python.keras.engine.training.Model', 'training.Model', ([], {}), False, 'from tensorflow.python.keras.engine import training\n'), (570, 'tensorflow.python.keras.engine.training.Model', 'training.Model', ([], {}), False, 'from tensorflow.python.keras.engine import training\n'), (579, 'tensorflow.python.keras.engine.training.Model', 'training.Model', ([], {}), False, 'from tensorflow.python.keras.engine import training\n'), (588, 'tensorflow.python.keras.engine.training.Model', 'training.Model', ([], {}), False, 'from tensorflow.python.keras.engine import training\n'), (597, 'tensorflow.python.keras.engine.training.Model', 'training.Model', ([], {}), False, 'from tensorflow.python.keras.engine import training\n'), (606, 'tensorflow.python.keras.engine.training.Model', 'training.Model', ([], {}), False, 'from tensorflow.python.keras.engine import training\n'), (621, 'tensorflow.python.training.tracking.tracking.AutoTrackable', 'tracking.AutoTrackable', ([], {}), False, 'from tensorflow.python.training.tracking import tracking\n'), (624, 'copy.copy', 'copy.copy', (['root.a'], {}), False, 'import copy\n'), (630, 'tensorflow.python.training.tracking.util.list_objects', 'util.list_objects', (['root.a'], {}), False, 'from tensorflow.python.training.tracking import util\n'), (638, 'tensorflow.python.training.tracking.tracking.AutoTrackable', 'tracking.AutoTrackable', ([], {}), False, 'from tensorflow.python.training.tracking import tracking\n'), (641, 'copy.deepcopy', 'copy.deepcopy', (['root.a'], {}), False, 'import copy\n'), (647, 'tensorflow.python.training.tracking.util.list_objects', 'util.list_objects', (['root.a'], {}), False, 'from tensorflow.python.training.tracking import util\n'), (655, 'tensorflow.python.training.tracking.tracking.AutoTrackable', 'tracking.AutoTrackable', ([], {}), False, 'from tensorflow.python.training.tracking import tracking\n'), (658, 'copy.copy', 'copy.copy', (['root.a'], {}), False, 'import copy\n'), (669, 'tensorflow.python.training.tracking.util.list_objects', 'util.list_objects', (['root.a'], {}), False, 'from tensorflow.python.training.tracking import util\n'), (677, 'tensorflow.python.training.tracking.tracking.AutoTrackable', 'tracking.AutoTrackable', ([], {}), False, 'from tensorflow.python.training.tracking import tracking\n'), (680, 'copy.deepcopy', 'copy.deepcopy', (['root.a'], {}), False, 'import copy\n'), (686, 'tensorflow.python.training.tracking.util.list_objects', 'util.list_objects', (['root.a'], {}), False, 'from tensorflow.python.training.tracking import util\n'), (694, 'tensorflow.python.training.tracking.tracking.AutoTrackable', 'tracking.AutoTrackable', ([], {}), False, 'from tensorflow.python.training.tracking import tracking\n'), (695, 'tensorflow.python.training.tracking.tracking.AutoTrackable', 'tracking.AutoTrackable', ([], {}), False, 'from tensorflow.python.training.tracking import tracking\n'), (698, 'copy.copy', 'copy.copy', (['original'], {}), False, 'import copy\n'), (702, 'tensorflow.python.training.tracking.util.list_objects', 'util.list_objects', (['shallow_copied'], {}), False, 'from tensorflow.python.training.tracking import util\n'), (708, 'tensorflow.python.training.tracking.tracking.AutoTrackable', 'tracking.AutoTrackable', ([], {}), False, 'from tensorflow.python.training.tracking import tracking\n'), (709, 'tensorflow.python.training.tracking.tracking.AutoTrackable', 'tracking.AutoTrackable', ([], {}), False, 'from tensorflow.python.training.tracking import tracking\n'), (712, 'copy.deepcopy', 'copy.deepcopy', (['original'], {}), False, 'import copy\n'), (717, 'tensorflow.python.training.tracking.util.list_objects', 'util.list_objects', (['deep_copied'], {}), False, 'from tensorflow.python.training.tracking import util\n'), (724, 'tensorflow.python.training.tracking.data_structures._DictWrapper', 'data_structures._DictWrapper', (['[(1, 2), (3, 4)]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (47, 'tensorflow.python.keras.layers.core.Dense', 'core.Dense', (['(4)'], {}), False, 'from tensorflow.python.keras.layers import core\n'), (52, 'tensorflow.python.keras.layers.core.Dense', 'core.Dense', (['(7)'], {'bias_regularizer': 'math_ops.reduce_sum'}), False, 'from tensorflow.python.keras.layers import core\n'), (53, 'tensorflow.python.keras.layers.core.Dense', 'core.Dense', (['(8)'], {}), False, 'from tensorflow.python.keras.layers import core\n'), (68, 'tensorflow.python.ops.math_ops.reduce_sum', 'math_ops.reduce_sum', (['x'], {}), False, 'from tensorflow.python.ops import math_ops\n'), (79, 'tensorflow.python.ops.array_ops.ones', 'array_ops.ones', (['[32, 2]'], {}), False, 'from tensorflow.python.ops import array_ops\n'), (111, 'tensorflow.python.eager.context.graph_mode', 'context.graph_mode', ([], {}), False, 'from tensorflow.python.eager import context\n'), (113, 'tensorflow.python.ops.array_ops.ones', 'array_ops.ones', (['[32, 2]'], {}), False, 'from tensorflow.python.ops import array_ops\n'), (119, 'tensorflow.python.eager.context.eager_mode', 'context.eager_mode', ([], {}), False, 'from tensorflow.python.eager import context\n'), (121, 'tensorflow.python.ops.array_ops.ones', 'array_ops.ones', (['[32, 2]'], {}), False, 'from tensorflow.python.ops import array_ops\n'), (181, 'tensorflow.python.eager.context.graph_mode', 'context.graph_mode', ([], {}), False, 'from tensorflow.python.eager import context\n'), (182, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (183, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', (['[inner]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (236, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (294, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[a, a]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (295, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[a, a]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (297, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[a, a]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (298, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[a, a]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (302, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[a, a]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (303, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[b, a]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (305, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[b, a]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (307, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[a]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (308, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[a, b]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (310, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[a]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (311, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[a, b]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (313, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[a, b]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (314, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[a]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (316, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[a, b]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (317, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[a]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (318, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[a]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (322, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[a]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (435, 'tensorflow.python.keras.layers.normalization.BatchNormalization', 'normalization.BatchNormalization', ([], {}), False, 'from tensorflow.python.keras.layers import normalization\n'), (437, 'tensorflow.python.keras.layers.normalization.BatchNormalization', 'normalization.BatchNormalization', ([], {}), False, 'from tensorflow.python.keras.layers import normalization\n'), (443, 'tensorflow.python.ops.math_ops.reduce_sum', 'math_ops.reduce_sum', (['x'], {}), False, 'from tensorflow.python.ops import math_ops\n'), (453, 'tensorflow.python.ops.array_ops.ones', 'array_ops.ones', (['[32, 2]'], {}), False, 'from tensorflow.python.ops import array_ops\n'), (466, 'numpy.ones', 'numpy.ones', (['[6, 7]'], {}), False, 'import numpy\n'), (474, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (485, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (505, 'tensorflow.python.training.tracking.data_structures.Mapping', 'data_structures.Mapping', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (529, 'tensorflow.python.training.tracking.util.list_objects', 'util.list_objects', (['a'], {}), False, 'from tensorflow.python.training.tracking import util\n'), (541, 'tensorflow.python.training.tracking.util.list_objects', 'util.list_objects', (['a'], {}), False, 'from tensorflow.python.training.tracking import util\n'), (558, 'tensorflow.python.training.tracking.tracking.AutoTrackable', 'tracking.AutoTrackable', ([], {}), False, 'from tensorflow.python.training.tracking import tracking\n'), (562, 'tensorflow.python.training.tracking.util.list_objects', 'util.list_objects', (['a'], {}), False, 'from tensorflow.python.training.tracking import util\n'), (633, 'tensorflow.python.training.tracking.util.list_objects', 'util.list_objects', (['root.a'], {}), False, 'from tensorflow.python.training.tracking import util\n'), (650, 'tensorflow.python.training.tracking.util.list_objects', 'util.list_objects', (['root.a'], {}), False, 'from tensorflow.python.training.tracking import util\n'), (672, 'tensorflow.python.training.tracking.util.list_objects', 'util.list_objects', (['root.a'], {}), False, 'from tensorflow.python.training.tracking import util\n'), (689, 'tensorflow.python.training.tracking.util.list_objects', 'util.list_objects', (['root.a'], {}), False, 'from tensorflow.python.training.tracking import util\n'), (46, 'tensorflow.python.keras.layers.core.Dense', 'core.Dense', (['(3)'], {}), False, 'from tensorflow.python.keras.layers import core\n'), (49, 'tensorflow.python.keras.layers.core.Dense', 'core.Dense', (['(5)'], {}), False, 'from tensorflow.python.keras.layers import core\n'), (50, 'tensorflow.python.keras.layers.core.Dense', 'core.Dense', (['(6)'], {'kernel_regularizer': 'math_ops.reduce_sum'}), False, 'from tensorflow.python.keras.layers import core\n'), (62, 'tensorflow.python.keras.layers.normalization.BatchNormalization', 'normalization.BatchNormalization', ([], {}), False, 'from tensorflow.python.keras.layers import normalization\n'), (99, 'tensorflow.python.ops.array_ops.zeros', 'array_ops.zeros', (['[2, 3]'], {}), False, 'from tensorflow.python.ops import array_ops\n'), (157, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (184, 'tensorflow.python.layers.core.Dense', 'non_keras_core.Dense', (['(1)'], {}), True, 'from tensorflow.python.layers import core as non_keras_core\n'), (185, 'tensorflow.python.ops.array_ops.ones', 'array_ops.ones', (['[2, 3]'], {}), False, 'from tensorflow.python.ops import array_ops\n'), (233, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (234, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (319, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', (['[a]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (320, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[a]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (321, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[a]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (349, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (428, 'tensorflow.python.keras.layers.core.Dense', 'core.Dense', (['(7)'], {}), False, 'from tensorflow.python.keras.layers import core\n'), (432, 'tensorflow.python.keras.layers.core.Dense', 'core.Dense', (['(5)'], {}), False, 'from tensorflow.python.keras.layers import core\n'), (433, 'tensorflow.python.keras.layers.core.Dense', 'core.Dense', (['(6)'], {'kernel_regularizer': 'math_ops.reduce_sum'}), False, 'from tensorflow.python.keras.layers import core\n'), (461, 'tensorflow.python.ops.array_ops.ones', 'array_ops.ones', (['[6, 7]'], {}), False, 'from tensorflow.python.ops import array_ops\n'), (464, 'tensorflow.python.ops.array_ops.zeros', 'array_ops.zeros', (['[6, 7]'], {}), False, 'from tensorflow.python.ops import array_ops\n'), (478, 'tensorflow.python.training.tracking.data_structures.Mapping', 'data_structures.Mapping', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (502, 'tensorflow.python.training.tracking.data_structures.Mapping', 'data_structures.Mapping', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (503, 'tensorflow.python.training.tracking.data_structures.Mapping', 'data_structures.Mapping', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (635, 'copy.copy', 'copy.copy', (['root.a'], {}), False, 'import copy\n'), (652, 'copy.deepcopy', 'copy.deepcopy', (['root.a'], {}), False, 'import copy\n'), (674, 'copy.copy', 'copy.copy', (['root.a'], {}), False, 'import copy\n'), (691, 'copy.deepcopy', 'copy.deepcopy', (['root.a'], {}), False, 'import copy\n'), (730, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[1.0]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (731, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[2.0]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (733, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[1.0]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (737, 'tensorflow.python.training.tracking.data_structures._ListWrapper', 'data_structures._ListWrapper', (['[2.0]'], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (56, 'tensorflow.python.keras.layers.core.Dense', 'core.Dense', (['(9)'], {}), False, 'from tensorflow.python.keras.layers import core\n'), (57, 'tensorflow.python.keras.layers.core.Dense', 'core.Dense', (['(10)'], {}), False, 'from tensorflow.python.keras.layers import core\n'), (161, 'tensorflow.python.training.tracking.data_structures.List', 'data_structures.List', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (480, 'tensorflow.python.training.tracking.data_structures.Mapping', 'data_structures.Mapping', ([], {}), False, 'from tensorflow.python.training.tracking import data_structures\n'), (60, 'tensorflow.python.keras.layers.core.Dense', 'core.Dense', (['(12)'], {}), False, 'from tensorflow.python.keras.layers import core\n'), (60, 'tensorflow.python.keras.layers.core.Dense', 'core.Dense', (['(11)'], {}), False, 'from tensorflow.python.keras.layers import core\n')]