1
Vote

BUG -- Expansion of Locals node gives wrong object

description

I have a Python program which uses a C extension called PyGLPK, version 0.3. It has a class LPX with two members rows and cols of class BarCollection. These collections have sequence behavior as well as mapping behavior, as in cols[xxx] or cols[10]. The member rows and columns are of class Bar. They have an attribute index which matches its position in the collection's sequence.
PTVS shows the numerically indexed elements as [0], [1],... The name for [10] reads something like <glpk.Bar, row 10 of glpk.LPX ...>. However, if I expand [10] I get the children of a different member of the collection, which I can tell because it has an index attribute which is not 10.
Now, if I type in list (mylpx.rows), I do get a list where [10] expands to something have index = 10.
If I Add Watch for item [10] in the expansion of mylpx.rows, it adds an item named mylpx.rows[10], which gives the correct result.
Here's a copy of the implementation for the BarCollection class and its related BarCollectionIter class (attached). You may also find the Bar and LPK implementations also useful, so I've attached these as well. If you need more, you can look up PyGLPK on the Python Packages site. To test this out yourself, you may want to load the GLPK and build the extension rather than try to simulate what it does. The extension methods use the underlying objects maintained by the GLPK library to get and set some of the attributes.
BTW, this package is a wrapper around the GNU Linear Programming Kit (GLPK) which comes as a DLL.

file attachments

comments

pminaev wrote Jun 17 at 9:06 PM

If you do "Add Watch" on the object in question, what does the resulting expression in the Watch window look like?

pminaev wrote Jun 17 at 9:15 PM

It looks like you're returning a new Bar object every time indexing happens, so I'd expect this bit in our debugger to go down the use_index==False route:
                    # Some objects are enumerable but not indexable, or repr(key) is not a valid Python expression. For those, we
                    # cannot use obj[key] to get the item by its key, and have to retrieve it by index from enumerate() instead.
                    try:
                        item_by_key = res[eval_repr(key)]
                        use_index = item is not item_by_key
                    except:
                        use_index = True
                    else:
                        use_index = False

                    item_name = '[' + key_repr + ']'
                    if use_index:
                        item_expr = 'next((v for i, %s in enumerate(%s) if i == %s))' % (enum_var, enum_expr, index)
                    else:
                        item_expr = expr + item_name
and so Watch should show the next(...) expression. The question is whether this expression does work correctly for your collection, and if not, then why not. I can't see any obvious reason as to why this would be broken (it can be broken if order of iteration is not stable, but this is not the case here).