0

Let's say I want to step into my function:

-> gene_signature = GeneSignature.from_geo(request.form)
(Pdb) s

What I always get next is:

--Call--
> ../venv/lib/python2.7/site-packages/werkzeug/local.py(335)__getattr__()
-> def __getattr__(self, name):
(Pdb) n
> ../venv/lib/python2.7/site-packages/werkzeug/local.py(336)__getattr__()
-> if name == '__members__':
(Pdb) n
> ../venv/lib/python2.7/site-packages/werkzeug/local.py(338)__getattr__()
-> return getattr(self._get_current_object(), name)
(Pdb) n
--Return--
> ../venv/lib/python2.7/site-packages/werkzeug/local.py(338)__getattr__()->Immutabl...iDict([])
-> return getattr(self._get_current_object(), name)
(Pdb) n

Only after these steps do I get:

--Call--
> ../model/genesignature.py(72)from_geo()
-> @classmethod

What's happening? Can I avoid stepping through this intermediate code?

jds
  • 7,910
  • 11
  • 63
  • 101

1 Answers1

1

Two things:

  1. __getattr__ is the built-in, overrideable method for accessing attributes on objects.

  2. You can avoid stepping into "intermediate code" in the debugger using n rather than s (You do this after the first time but not the first time, so it "steps" into this call.)

Edited to add: It sounds like you are torn between n and s at this point because your break point is in the wrong place. Move it to start inside the function so you aren't stuck either stepping over it or too far into it.

Two-Bit Alchemist
  • 17,966
  • 6
  • 47
  • 82
  • Right. My guess is that `werkzeug` is working to get my request arguments. But if I type `n`, I avoid `GeneSignature.from_geo(request.form)` entirely, going to the next line. Maybe accessing `request.form` is what calls `__getattr__`. – jds Aug 26 '15 at 20:10
  • No, my theory is correct. If I write `args = request.form; gene_signature = GeneSignature.from_geo(args)` then I can step over the `werkzeug` code and then when I type `s` for `from_geo`, I immediately step into that function. – jds Aug 26 '15 at 20:15
  • Maybe I'm imagining this wrong (apologies if this is just a misunderstanding), but I'm saying it sounds to me like your `set_trace()` should be the first statement in `from_geo` and that at this point it is somewhere just before it. Is this not right? – Two-Bit Alchemist Aug 26 '15 at 20:21
  • Well, you're right moving the breakpoint would avoid the problem, but often I want to put my breakpoint near the top of the stack and monitor the program as I step through it. Sometimes I want to step into `from_geo`; sometimes I don't. I've encountered this `__getattr__` function every time I stepped into `from_geo` and I'm wasn't sure why it was being called. It doesn't get called when I dereference a value on a `dict`, for example. But now I think I know why (thanks to rubber ducking with you): it gets called because the `werkzeug` module is overriding the built-in. – jds Aug 26 '15 at 20:29