module name versus function name resolution conflict.


R

rocky

Someone recently reported a problem in pydb where a function defined
in his program was conflicting with a module name that pydb uses. I
think I understand what's wrong, but I don't have any elegant
solutions to the problem. Suggestions would be appreciated.

In a nutshell, here's the problem:

In file fns:

def foo(): print "foo"

In file pdebug.py:

import fns, sys

def trace_dispatch(frame, event, arg):
fns.foo()
print frame, event, arg
return trace_dispatch

sys.settrace(trace_dispatch)
execfile('myprogram.py')

Finally file myprogram.py:

def fns(): print "This is the *other* fns"

When you run pdebug.py you get:

$ python pdebug.py
foo
<frame object at 0xdd9030> call None
foo
<frame object at 0xdd9030> line None
Traceback (most recent call last):
File "pdebug.py", line 7, in <module>
execfile('myprogram.py')
File "myprogram.py", line 1, in <module>
def fns(): print "This is the *other* fns"
File "pdebug.py", line 3, in trace_dispatch
fns.foo()
AttributeError: 'function' object has no attribute 'foo'


Basically inside the trace hook, local functions are visible and take
precedence over (global) module names. I could move "import fns"
inside trace_dispatch(), but I'd have to do that in all of the methods
that module "fns" is used. Also note that using the form:
from fns import foo

would eliminate the conflict on "fns", but I'd still have potential
conflicts on "foo". Using more obscure names (e.g. pydb_fns) would
reduce the chance of a conflict but not eliminate it.

Suggestions?
 
Ad

Advertisements

P

Peter Otten

rocky said:
Someone recently reported a problem in pydb where a function defined
in his program was conflicting with a module name that pydb uses. I
think I understand what's wrong, but I don't have any elegant
solutions to the problem. Suggestions would be appreciated.

In a nutshell, here's the problem:

In file fns:

def foo(): print "foo"

In file pdebug.py:

import fns, sys

def trace_dispatch(frame, event, arg):
fns.foo()
print frame, event, arg
return trace_dispatch

sys.settrace(trace_dispatch)
execfile('myprogram.py')

Finally file myprogram.py:

def fns(): print "This is the *other* fns"

When you run pdebug.py you get:

$ python pdebug.py
foo
<frame object at 0xdd9030> call None
foo
<frame object at 0xdd9030> line None
Traceback (most recent call last):
File "pdebug.py", line 7, in <module>
execfile('myprogram.py')
File "myprogram.py", line 1, in <module>
def fns(): print "This is the *other* fns"
File "pdebug.py", line 3, in trace_dispatch
fns.foo()
AttributeError: 'function' object has no attribute 'foo'


Basically inside the trace hook, local functions are visible and take
precedence over (global) module names. I could move "import fns"
inside trace_dispatch(), but I'd have to do that in all of the methods
that module "fns" is used. Also note that using the form:
from fns import foo

would eliminate the conflict on "fns", but I'd still have potential
conflicts on "foo". Using more obscure names (e.g. pydb_fns) would
reduce the chance of a conflict but not eliminate it.

Suggestions?

Can you run the program in another namespace?

execfile("myprogram.py", {"__name__":"__main__"})

Alternatively move trace_dispatch into yet another module and import it into
pdebug.

from elsewhere import trace_dispatch

Peter
 
Ad

Advertisements

R

rocky

I was sloppy here. The "local" is the wrong word as suggested by the
first remedy proposed.
"entry in the global namespace dictionary" is probably closer to the
truth.
Can you run the program in another namespace?

execfile("myprogram.py", {"__name__":"__main__"})

Alternatively move trace_dispatch into yet anothermoduleand import it into
pdebug.

from elsewhere import trace_dispatch

Peter

Both of these work. Thanks! (I haven't figured out how to adapt it to
the messier context of the program yet). The second suggestion
interesting/weird:
by putting trace_dispatch in another module, compilation and name/
function resolution of fns.foo
is done before myprogram has a chance to redefine fns.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top