def test_iter_objects_allow_object_cannot_compare_for_equality(self):
        # see enthought/traits#1277
        foo = Foo()
        foo.any_value = CannotCompare()

        actual = list(helpers.iter_objects(foo, "any_value"))
        self.assertEqual(actual, [foo.any_value])
 def test_iter_objects_does_not_evaluate_default(self):
     foo = Foo()
     list(helpers.iter_objects(foo, "int_with_default"))
     self.assertFalse(
         foo.int_with_default_computed,
         "Expect the default not to have been computed."
     )
    def test_iter_objects_avoid_undefined(self):
        foo = Foo()
        # sanity check
        self.assertNotIn("instance", foo.__dict__)

        actual = list(helpers.iter_objects(foo, "instance"))
        self.assertEqual(actual, [])
Example #4
0
    def iter_objects(self, object):
        """ Yield the values of the traits that match the given filter. The
        values will be given to the next observer(s) following this one in an
        ObserverGraph.

        If a value has not been set as an instance attribute, i.e. absent in
        ``object.__dict__``, this observer will skip it. This is to avoid
        evaluating default initializers while adding observers. When the
        default is defined, a change event will trigger the maintainer to
        add/remove notifiers for the next observers.

        Note that ``Undefined``, ``Uninitialized`` and ``None`` values are also
        skipped, as they are unavoidable filled values that contain no further
        attributes to be observed by any other observers.

        Parameters
        ----------
        object: object
            Object provided by the ``iter_objects`` methods from another
            observers or directly by the user.

        Yields
        ------
        value : object
        """
        for name, ctrait in object.traits().items():
            if self.filter(name, ctrait):
                yield from iter_objects(object, name)
Example #5
0
    def iter_objects(self, object):
        """ Yield the value of the named trait from the given object, if the
        value is defined. The value will then be given to the next observer(s)
        following this one in an ObserverGraph.

        If the value has not been set as an instance attribute, i.e. absent in
        ``object.__dict__``, this observer will yield nothing. This is to avoid
        evaluating default initializers while adding observers. When the
        default is defined, a change event will trigger the maintainer to
        add/remove notifiers for the next observers.

        Note that ``Undefined``, ``Uninitialized`` and ``None`` values are also
        skipped, as they are inevitable filled values that contain no further
        attributes to be observed by any other observers.

        Parameters
        ----------
        object: HasTraits
            Expected to be an instance of HasTraits

        Yields
        ------
        value : any

        Raises
        ------
        ValueError
            If the trait is not found and optional flag is set to false.
        """
        if not object_has_named_trait(object, self.name):
            if self.optional:
                return
            raise ValueError("Trait named {!r} not found on {!r}.".format(
                self.name, object))
        yield from iter_objects(object, self.name)
    def test_iter_objects_no_sideeffect(self):
        foo = Foo()
        # sanity check
        self.assertNotIn("instance", foo.__dict__)

        list(helpers.iter_objects(foo, "instance"))

        self.assertNotIn("instance", foo.__dict__)
    def test_no_warn_for_property(self):
        # property is computed and downstream observers are not useful.
        # they do exist in the wild. Do not warn for those.

        instance = ObjectWithEqualityComparisonMode()

        # almost equivalent to assertNoWarns...
        with self.assertRaises(AssertionError):
            with self.assertWarns(RuntimeWarning):
                list(helpers.iter_objects(instance, "property_list"))
    def test_warn_list_explicit_equality_comparison_mode(self):
        # Test a warning is emitted if the comparison mode is explicitly set to
        # equality. Note that iter_objects is for providing values for the
        # next observers, hence imitates the use case when membership in a
        # container is observed.
        instance = ObjectWithEqualityComparisonMode()

        name_to_type = {
            "list_values": "List",
            "dict_values": "Dict",
            "set_values": "Set",
            "container_in_union": "Union",
        }
        for trait_name, type_name in name_to_type.items():
            with self.subTest(trait_name=trait_name, type_name=type_name):

                with self.assertWarns(RuntimeWarning) as warn_context:
                    list(helpers.iter_objects(instance, trait_name))

                self.assertIn(
                    "Redefine the trait with {}(..., comparison_mode".format(
                        type_name), str(warn_context.warning))
 def test_iter_objects_does_not_trigger_property(self):
     foo = Foo()
     list(helpers.iter_objects(foo, "property_value"))
     self.assertEqual(foo.property_n_calculations, 0)
    def test_iter_objects_accepted_values(self):
        foo = Foo(instance=Bar(), list_of_int=[1, 2])
        actual = list(helpers.iter_objects(foo, "instance"))

        self.assertEqual(actual, [foo.instance])
    def test_iter_objects_avoid_none(self):
        foo = Foo()
        foo.instance = None

        actual = list(helpers.iter_objects(foo, "instance"))
        self.assertEqual(actual, [])
 def iter_objects(self, object):
     """ Yield only the value for the named trait."""
     yield from iter_objects(object, self.name)