<div dir="ltr">Diff looks like this:<div><br></div><div><pre style="color:rgb(0,0,0);line-height:normal;word-wrap:break-word;white-space:pre-wrap"><pre style="word-wrap:break-word;white-space:pre-wrap">-                @dwarf_test
-                @wraps(attrvalue)
-                def dwarf_test_method(self, attrvalue=attrvalue):
-                    self.debug_info = "dwarf"
-                    return attrvalue(self)
-                dwarf_method_name = attrname + "_dwarf"
-                dwarf_test_method.__name__ = dwarf_method_name
-                newattrs[dwarf_method_name] = dwarf_test_method</pre>...</pre><pre style="color:rgb(0,0,0);line-height:normal;word-wrap:break-word;white-space:pre-wrap">+                for category in supported_categories:
+                    @add_test_categories([category])
+                    @wraps(attrvalue)
+                    def test_method(self, attrvalue=attrvalue):
+                        self.debug_info = category
+                        return attrvalue(self)
+                    method_name = attrname + "_" + category
+                    test_method.__name__ = method_name
+                    newattrs[method_name] = test_method</pre><pre style="color:rgb(0,0,0);line-height:normal;word-wrap:break-word;white-space:pre-wrap"><br></pre><pre style="color:rgb(0,0,0);line-height:normal;word-wrap:break-word;white-space:pre-wrap"><span style="color:rgb(33,33,33);font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:13px;line-height:19.5px;white-space:normal">So it looks like it's still under a different function.  The difference is that before (in the - section of the diff) there were 3 different functions with 3 different names.  For example `dwarf_test_method` above.  In the new code (+ section of the diff) it looks like one function defined 3 different times with the same name `test_method`.  But each of these should be a distinct function object that is defined in the context of the closure determined by the enclosing scope (the for loop in this case).  So all 3 functions are actually different.  self is just an argument to the function, not some magic value like `this` in C++, so as in the previous version, the `debug_info` that gets modified is on whatever instance of `self` gets passed into the function, same as before.</span><br></pre><pre style="color:rgb(0,0,0);line-height:normal;word-wrap:break-word;white-space:pre-wrap"><span style="color:rgb(33,33,33);font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:13px;line-height:19.5px;white-space:normal">Tamas or Pavel can probably clarify, but that's my understanding.</span><br></pre></div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Dec 14, 2015 at 2:09 PM Siva Chandra <<a href="mailto:sivachandra@google.com">sivachandra@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Previously, self.debug_info was under different functions<br>
(dwarf_test_method, dwo_test_method etc.). Now, they are all under<br>
test_method. Even I am equally ignorant about the Python nuances here.<br>
<br>
On Mon, Dec 14, 2015 at 2:04 PM, Zachary Turner <<a href="mailto:zturner@google.com" target="_blank">zturner@google.com</a>> wrote:<br>
> The previous code was just an unrolled loop as far as I can tell.  Do you<br>
> mean the loop has different behavior than the unrolled loop?  Because it<br>
> looks identical to me (although admittedly python has a lot of nuances that<br>
> I don't understand in great detail)<br>
><br>
> On Mon, Dec 14, 2015 at 1:59 PM Siva Chandra <<a href="mailto:sivachandra@google.com" target="_blank">sivachandra@google.com</a>> wrote:<br>
>><br>
>> On Mon, Dec 14, 2015 at 10:49 AM, Zachary Turner via lldb-commits<br>
>> <<a href="mailto:lldb-commits@lists.llvm.org" target="_blank">lldb-commits@lists.llvm.org</a>> wrote:<br>
>> > Modified: lldb/trunk/packages/Python/lldbsuite/test/lldbtest.py<br>
>> > URL:<br>
>> > <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lldbtest.py?rev=255525&r1=255524&r2=255525&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lldbtest.py?rev=255525&r1=255524&r2=255525&view=diff</a><br>
>> ><br>
>> > ==============================================================================<br>
>> > --- lldb/trunk/packages/Python/lldbsuite/test/lldbtest.py (original)<br>
>> > +++ lldb/trunk/packages/Python/lldbsuite/test/lldbtest.py Mon Dec 14<br>
>> > 12:49:16 2015<br>
>> > @@ -549,48 +549,6 @@ def no_debug_info_test(func):<br>
>> >      wrapper.__no_debug_info_test__ = True<br>
>> >      return wrapper<br>
>> ><br>
>> > -def dsym_test(func):<br>
>> > -    """Decorate the item as a dsym test."""<br>
>> > -    if isinstance(func, type) and issubclass(func, unittest2.TestCase):<br>
>> > -        raise Exception("@dsym_test can only be used to decorate a test<br>
>> > method")<br>
>> > -    @wraps(func)<br>
>> > -    def wrapper(self, *args, **kwargs):<br>
>> > -        if configuration.dont_do_dsym_test:<br>
>> > -            self.skipTest("dsym tests")<br>
>> > -        return func(self, *args, **kwargs)<br>
>> > -<br>
>> > -    # Mark this function as such to separate them from the regular<br>
>> > tests.<br>
>> > -    wrapper.__dsym_test__ = True<br>
>> > -    return wrapper<br>
>> > -<br>
>> > -def dwarf_test(func):<br>
>> > -    """Decorate the item as a dwarf test."""<br>
>> > -    if isinstance(func, type) and issubclass(func, unittest2.TestCase):<br>
>> > -        raise Exception("@dwarf_test can only be used to decorate a<br>
>> > test method")<br>
>> > -    @wraps(func)<br>
>> > -    def wrapper(self, *args, **kwargs):<br>
>> > -        if configuration.dont_do_dwarf_test:<br>
>> > -            self.skipTest("dwarf tests")<br>
>> > -        return func(self, *args, **kwargs)<br>
>> > -<br>
>> > -    # Mark this function as such to separate them from the regular<br>
>> > tests.<br>
>> > -    wrapper.__dwarf_test__ = True<br>
>> > -    return wrapper<br>
>> > -<br>
>> > -def dwo_test(func):<br>
>> > -    """Decorate the item as a dwo test."""<br>
>> > -    if isinstance(func, type) and issubclass(func, unittest2.TestCase):<br>
>> > -        raise Exception("@dwo_test can only be used to decorate a test<br>
>> > method")<br>
>> > -    @wraps(func)<br>
>> > -    def wrapper(self, *args, **kwargs):<br>
>> > -        if configuration.dont_do_dwo_test:<br>
>> > -            self.skipTest("dwo tests")<br>
>> > -        return func(self, *args, **kwargs)<br>
>> > -<br>
>> > -    # Mark this function as such to separate them from the regular<br>
>> > tests.<br>
>> > -    wrapper.__dwo_test__ = True<br>
>> > -    return wrapper<br>
>> > -<br>
>> >  def debugserver_test(func):<br>
>> >      """Decorate the item as a debugserver test."""<br>
>> >      if isinstance(func, type) and issubclass(func, unittest2.TestCase):<br>
>> > @@ -2270,32 +2228,26 @@ class LLDBTestCaseFactory(type):<br>
>> >          newattrs = {}<br>
>> >          for attrname, attrvalue in attrs.items():<br>
>> >              if attrname.startswith("test") and not getattr(attrvalue,<br>
>> > "__no_debug_info_test__", False):<br>
>> > -                @dsym_test<br>
>> > -                @wraps(attrvalue)<br>
>> > -                def dsym_test_method(self, attrvalue=attrvalue):<br>
>> > -                    self.debug_info = "dsym"<br>
>> > -                    return attrvalue(self)<br>
>> > -                dsym_method_name = attrname + "_dsym"<br>
>> > -                dsym_test_method.__name__ = dsym_method_name<br>
>> > -                newattrs[dsym_method_name] = dsym_test_method<br>
>> > -<br>
>> > -                @dwarf_test<br>
>> > -                @wraps(attrvalue)<br>
>> > -                def dwarf_test_method(self, attrvalue=attrvalue):<br>
>> > -                    self.debug_info = "dwarf"<br>
>> > -                    return attrvalue(self)<br>
>> > -                dwarf_method_name = attrname + "_dwarf"<br>
>> > -                dwarf_test_method.__name__ = dwarf_method_name<br>
>> > -                newattrs[dwarf_method_name] = dwarf_test_method<br>
>> > -<br>
>> > -                @dwo_test<br>
>> > -                @wraps(attrvalue)<br>
>> > -                def dwo_test_method(self, attrvalue=attrvalue):<br>
>> > -                    self.debug_info = "dwo"<br>
>> > -                    return attrvalue(self)<br>
>> > -                dwo_method_name = attrname + "_dwo"<br>
>> > -                dwo_test_method.__name__ = dwo_method_name<br>
>> > -                newattrs[dwo_method_name] = dwo_test_method<br>
>> > +                target_platform =<br>
>> > lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]<br>
>> > +<br>
>> > +                # If any debug info categories were explicitly tagged,<br>
>> > assume that list to be<br>
>> > +                # authoritative.  If none were specified, try with all<br>
>> > debug info formats.<br>
>> > +                all_dbginfo_categories =<br>
>> > set(test_categories.debug_info_categories)<br>
>> > +                categories = set(getattr(attrvalue, "categories", []))<br>
>> > & all_dbginfo_categories<br>
>> > +                if not categories:<br>
>> > +                    categories = all_dbginfo_categories<br>
>> > +<br>
>> > +                supported_categories = [x for x in categories<br>
>> > +                                        if<br>
>> > test_categories.is_supported_on_platform(x, target_platform)]<br>
>> > +                for category in supported_categories:<br>
>> > +                    @add_test_categories([category])<br>
>> > +                    @wraps(attrvalue)<br>
>> > +                    def test_method(self, attrvalue=attrvalue):<br>
>> > +                        self.debug_info = category<br>
>><br>
>> I believe test methods are added here to the same class. In which<br>
>> case, self.debug_info is overwritten with each iteration of this for<br>
>> loop.<br>
>><br>
>> > +                        return attrvalue(self)<br>
>> > +                    method_name = attrname + "_" + category<br>
>> > +                    test_method.__name__ = method_name<br>
>> > +                    newattrs[method_name] = test_method<br>
>> >              else:<br>
>> >                  newattrs[attrname] = attrvalue<br>
>> >          return super(LLDBTestCaseFactory, cls).__new__(cls, name,<br>
>> > bases, newattrs)<br>
</blockquote></div>