Debugging, as, script!

Aug 18, 2013 at 3:44 AM
Hi, I have recently installed PTVS 2.0 (Beta) and Visual Shell 2013.

I have two files,, and,

I am wondering, about, debugging.

I set a breakpoint, in, and, debug, and, as I would expect, it is hit, correctly. Now, as I know, autograder uses some things, in, however, if I set a breakpoint in this (search) file, it is not hit.

How is this?

Thanks! :)
Aug 18, 2013 at 4:36 AM
Can you clarify what the line that you set a breakpoint on looks like? The debugger will let you set breakpoints on any line in the file, but some of those lines are not actually counted as "hit" in any circumstances - for example, if you have a multiline statement. You can see some examples here:
Aug 18, 2013 at 9:03 AM
Hi. The file "" looks like this:
    print "aaaaaaaa"
    start = problem.getStartState()
    curPath = list(start)
    fringe = util.Stack()
    return theSearch(fringe)
I have a breakpoint on each of these lines. not a single one is hit, apparently, but, the code is still executed :s :)
Aug 18, 2013 at 9:34 AM
How does your other file uses this one? It doesn't look like something you would import; do you use exec?
Aug 18, 2013 at 11:41 AM
Unfortunately, it is a bit complicated. Autograder is a file, provided by the grader of a class, and it uses some other files, that end up using search. Not sure exactly, of the inner details of this.

This is what autograder looks like:
if __name__ == '__main__':
    options = readCommand(sys.argv)
    if options.generateSolutions:
    codePaths = options.studentCode.split(',')
    # moduleCodeDict = {}
    # for cp in codePaths:
    #     moduleName = re.match('.*?([^/]*)\.py', cp).group(1)
    #     moduleCodeDict[moduleName] = readFile(cp, root=options.codeRoot)
    # moduleCodeDict['projectTestClasses'] = readFile(options.testCaseCode, root=options.codeRoot)
    # moduleDict = loadModuleDict(moduleCodeDict)
    moduleDict = {}
    for cp in codePaths:
        moduleName = re.match('.*?([^/]*)\.py', cp).group(1)
        moduleDict[moduleName] = loadModuleFile(moduleName, os.path.join(options.codeRoot, cp))
    moduleName = re.match('.*?([^/]*)\.py', options.testCaseCode).group(1)     
    moduleDict['projectTestClasses'] = loadModuleFile(moduleName, os.path.join(options.codeRoot, options.testCaseCode))    
    if options.runTest != None:
        runTest(options.runTest, moduleDict, printTestCase=options.printTestCase)
        evaluate(options.generateSolutions, options.testRoot, moduleDict, 
            edxOutput=options.edxOutput, muteOutput=options.muteOutput, printTestCase=options.printTestCase,
and the last part ("evaluate") ends up calling, though, I do not know, if directly, or, indirectly, the methods in In Idle, I can set a breakpoint in search, and it gets hit. but idle debugging sucks ;). If it gets hit, in idle, however, I would expect it to hit in PTVS as well??

Thanks for your help, by the way! Great :)
Aug 18, 2013 at 8:16 PM
Edited Aug 18, 2013 at 8:16 PM
The tricky part when dealing with modules is whether the loaded module "knows" of its filename, because we need this to map VS breakpoints (which are defined as filename + line number, basically) to a particular line of Python code. When you import a module in a normal fashion, this just works, but if you use something fancy like reading the file into a string and then eval'ing or exec'ing it, the resulting code object in memory may not have any filename associated with it, unless you have explicitly provided it in the right place when using those APIs.

Try printing out __file__ from inside and see what that gives you.

IDLE uses the same fundamental Python APIs to implement its debugger, but the implementation is different from PTVS, so it may well behave differently. Although if my hypothesis is correct, I can't imagine how they can still make it all work..
Aug 18, 2013 at 10:29 PM
Edited Aug 18, 2013 at 10:30 PM
Thanks, pminaev, for your help! I tried printing
, and it gives "search.pyc". Haven't used all this in a long time, but, it seems to me, that that is, what it should give?
"search.pyc" is in the same folder as I would assume, it is the "compiled" version of of this file?

Thanks, again! Great job, on helping, here in this forum!
Aug 19, 2013 at 9:45 PM
This is reasonable, but unusual in that you've got a relative file path rather than an absolute one. Normally, you'd only get .pyc for imported modules, and then you'd also get an absolute file name for such modules. But even so, we should be handling this scenario correctly, so it definitely sounds like there is a bug in our debugger somewhere.

I tried to get a repro with simple two-module set-up with no project, one module importing another, breakpoints in the second module (both global and inside the function), and launching by right-clicking on the tab and doing "Start with Debugging". I also didn't have any luck with the same inside a project. So it would seem that whatever causes this behavior is specific to your code, and it is hard to say what it might be without looking at it.

Can you share the full source code for your loadModuleFile function? I think that whatever is causing this unusual behavior is likely triggered by the code in there, so if I can see it, I might be able to tell what the problem is - or at least get a local repro that I can debug.
Aug 19, 2013 at 10:34 PM
Sure, if I can help make this EVEN BETTER, I hope I can help. Apologize for the "ads", have uploaded it here: TEXT.

this is from a course. I am only supposed to edit, and, then, run

The code being called in is at line 105, 106, etc. Breakpoints there, do not get hit.

Aug 19, 2013 at 10:48 PM

btw, both and google drive are better options for uploading files :)
Aug 19, 2013 at 11:12 PM
ah ok, will have a look at those, as well! :)
Aug 20, 2013 at 1:15 AM
can you let me know, if you can reproduce, please :) Thanks :)
Aug 20, 2013 at 1:29 AM
Yes, I can reproduce it on your code taken verbatim, though I have not been able to condense it down to a simpler repro so far - which I would like to do before opening a bug for this so that I can describe the problem accurately. I'll follow up with the link to the bug as soon as I do that.

Thank you for providing the code - this is very helpful in resolving this!
Aug 20, 2013 at 1:49 AM
awesome. maybe, it can go in the next release then! Glad I can provide some "little" help!

Thanks again, apart from that I think PTVS is awesome, keep up the great work! :)
Aug 20, 2013 at 2:29 AM
Edited Aug 20, 2013 at 2:29 AM
This is rather intricate, indeed. The bug with a minimal repro is here:

I don't think we'll get to it anytime soon, as it is a very narrow scenario which requires a lot of deliberate manual fudging with Python import machinery to be triggered. In the meantime, I would recommend to fix the code so that it tries to do the same thing that a regular Python import does with respect to file paths, so that one and the other can be used side by side with no inconsistencies. The simplest way to do so with minimal modifications to the provided code is to use abspath, e.g.:
def loadModuleFile(moduleName, filePath):
    from os.path import abspath
    with open(filePath, 'r') as f:
        return imp.load_module(moduleName, f, abspath("" % moduleName), (".py", "r", imp.PY_SOURCE))
With this change to the code, your breakpoints should be hit as expected.
Aug 20, 2013 at 2:30 AM
ill give it a shot. Thanks! ;)
Aug 20, 2013 at 2:54 AM
ok, not sure if this is my python skills, but, I did what you said, and, it works, which, is great, but:

I now execute this code:
    print "aaaaaaaa"
    print __file__
    start = problem.getStartState()
    a = problem.isGoalState(start)
    curPath = list(start)
    fringe = util.Stack()
    return theSearch(fringe)
which calls this:
def theSearch(fringe):

    if fringe.isEmpty():
        return list()
    latestPath = fringe.pop()
    if problem.isGoalState(latestPath[-1]):
        return latestPath
        successors = problem.getSuccessors(latestPath[-1])
        if len(successors) == 0:
           # for path
and, once it gets to
if problem.isGoalState(latestPath[-1]):
, I step into the method (f11). Unfortunately, however, it does not do this, instead, it skips to line 112
return theSearch(fringe)
Is there something wrong, with my code?? I don't see it. or is it the debugger again?

Thanks, again!

Aug 20, 2013 at 4:26 PM
Ah ok, I had some missing stuff, in the code.

I guess, since python is an "interpreted language", one can only see if the code works, once your run it, i.e., no way to "compile" the code and see "compile" errors.