What happens here is that the NewView object participates in the reference loop, and the objects in this loop are not automatically collected as part of the primary selection mechanism based on CPython counting. However, they should eventually be collected as part of the CPython circular garbage collector, or you can force this collection to execute gc.collect() , so there should be no real memory leak.
Ironically, an attempt to discover that a possible collection by adding the __del__ method to NewView hinders the process because it displays a NewView object that is not possible: at least in Python 2, Python will not try to collect loops containing objects that have __del__ methods. See gc docs for more details. (Python 3 is a little smarter here, thanks to the changes outlined in PEP __del__ ) Thus, using the __del__ method using Python 2, a slow memory leak will occur over time. The solution is to remove the __del__ method.
Here is a graph showing the reference loop (in fact, this shows the entire strongly-connected component of the object graph containing the NewView object): nodes are the objects involved, and the arrows go from referrers to referents. In the lower right part of the graph, you see that the NewView object has a link to its upper level Group (via the content attribute) and that the Group object has a link to the view source text ( container attribute). Similar loops occur elsewhere in the view.

It is probably worth opening a function request on the Trace UI tracker: theoretically, it should be possible to break the reference cycles manually when the view is no longer needed, although in practice this may require a significant alteration of the source of user interfaces.
Here's some code demonstrating that (when deleting the __del__ methods) a call to gc.collect collects a NewView object: it stores a weak link to the view of instance A with a callback that tells you when that view collects garbage.
from traits.api import HasTraits, Int, Instance from traitsui.api import View import gc import weakref class NewView(View): pass def report_collection(ref): print("NewView object has been collected") class A(HasTraits): a = Int def default_traits_view(self): new_view = NewView('a') self.view_ref = weakref.ref(new_view, report_collection) return new_view def open_view(): a = A() a.configure_traits() print("Collecting cyclic garbage") gc.collect() print("Cyclic garbage collection complete")
On my machine, this is what I see when open_view called:
>>> open_view() Collecting cyclic garbage NewView object has been collected Cyclic garbage collection complete