Big problem fetching members from dynamically loaded module

P

Philippe C. Martin

Hi,

I'm getting pretty desperate here:

The code below crashes on the last line (but works from a shell).

The class 'BC' exists and the loop on self.__BC_EXEC_LIST passes fine.

It's got to be something really stupid but I've been looking at it too long
I guess.

Any clue would be quite welcome.

Regards,

Philippe






__EXEC_LIST = [ \
'import os', \
'import sys', \
'from SC.pilot.SC_Script_Processor import *', \
'from SC.utils.SC_Convert import *', \
'import string ', \
'from SC.iso.SC_Dec_ISO import *', \
'from SC.iso.SC_Enc_ISO import *', \
'from SC.iso.SC_Analysis import *', \
'sc_sp = SC_Script_Processor ()', \
'sc_enc = SC_Enc_ISO ()', \
'sc_dec = SC_Dec_ISO ()', \
'sc_a = SC_Analysis ()', \
'sc_conv = SC_Convert()' ]

__BC_EXEC_LIST = ['from SC.CARDS.BC import *','from
SC.Solutions.SCF.BCInterface import *','sc_bc = BC_Interface()']


for l_s in self.__BC_EXEC_LIST: #this loop works fine
try:
exec (l_s, self.m_process_global,self.m_process_local)

except:
traceback.print_exc()

for l_s in self.__EXEC_LIST: #this loop works fine
try:
exec (l_s, self.m_process_global,self.m_process_local)

except:
print >> sys.stderr, 'FATAL INIT ERROR - PLEASE CHECK YOUR
CONFIGURATION'

l = inspect.getmembers(eval('SC_Dec_ISO')) #THIS WORKS - the class
exists
l = inspect.getmembers(eval('BC')) #THIS CRASHES - the class exists
 
P

Philippe C. Martin

Hi,

Hopefully to make things clearer: this works from a shell:

In [23]:from SC.CARDS.BC import *

In [24]:l = inspect.getmembers(eval('BC'))

#l will get all members from class 'BC' whereas the code referenced below
gets an exception saying 'BC' is not defined.

Thanks,

Philippe
 
P

Philippe C. Martin

Hi,

I found the solution to my problem:

Besides the fact I still have no clue as to how the Python name spacing
works, the code I though did stuff (the __EXEC_LIST loop) did not do as I
expected as I had already imported all of the modules in an explicit
manner.

So now I can rephrase my problem:

1) I have a program (XYZ) which displays class members in menus
2) At the time I write my program, I do not know what class members should
be in thos menus
3) So I have the class names in external files so that I can send new
modules to the 'customer' without having to release a new version of 'XYZ'

What puzzles me furher is that the 'exec' of commands such as 'sc_bc = BC()'
do work as I use them further in 'XYZ' whereas the exec of 'from xxxxxxx
import *' does not _seem_ to do anything.

Grrr! I feel more stupid every day !

Any insight ?

Thanks,

Philippe
 
P

Peter Otten

Philippe said:
l = inspect.getmembers(eval('BC')) #THIS CRASHES - the class exists

Care to provide the traceback?
In [23]:from SC.CARDS.BC import *

In [24]:l = inspect.getmembers(eval('BC'))

What happened in lines 1 through 22? My guess would be

In [13]:from SC.CARDS import *

Be that as is may, eval("BC") can be simplified to BC,

from module import *

is the last roadhouse en route to chaos and an unqualified

try ... except

shows you are willing to drive with defunct brakes. By introducing exec and
eval() you are throwing the steering wheel out of the window.

Seriously, try to make do with __import__() and getattr() to clean up your
code a bit.

Driving-analogies-well-beyond-the-abyss-ly yours
Peter
 
P

Philippe C. Martin

OK Peter, first of all thanks.

You seem to be German and although I leave in the states, I'm French and
your english is clearly far more advanced than mine: I have yet to
understand a few of your comments ;-)
Care to provide the traceback?

Traceback (most recent call last):
File "SC_Shell.py", line 1095, in ?
l_d = SC_Shell()
File "SC_Shell.py", line 326, in __init__
self.__Make_Menu_Area()
File "SC_Shell.py", line 828, in __Make_Menu_Area
l = inspect.getmembers(eval(c))
What happened in lines 1 through 22? My guess would be
just import inspect


and after that .... QUID ?

Thanks and regards,

Philippe





Peter said:
Philippe said:
l = inspect.getmembers(eval('BC')) #THIS CRASHES - the class exists

Care to provide the traceback?
In [23]:from SC.CARDS.BC import *

In [24]:l = inspect.getmembers(eval('BC'))

What happened in lines 1 through 22? My guess would be

In [13]:from SC.CARDS import *

Be that as is may, eval("BC") can be simplified to BC,

from module import *

is the last roadhouse en route to chaos and an unqualified

try ... except

shows you are willing to drive with defunct brakes. By introducing exec
and eval() you are throwing the steering wheel out of the window.

Seriously, try to make do with __import__() and getattr() to clean up your
code a bit.

Driving-analogies-well-beyond-the-abyss-ly yours
Peter
 
P

Philippe C. Martin

I meant live, not leave ! (this is getting pretty bad)

OK Peter, first of all thanks.

You seem to be German and although I leave in the states, I'm French and
your english is clearly far more advanced than mine: I have yet to
understand a few of your comments ;-)
Care to provide the traceback?

Traceback (most recent call last):
File "SC_Shell.py", line 1095, in ?
l_d = SC_Shell()
File "SC_Shell.py", line 326, in __init__
self.__Make_Menu_Area()
File "SC_Shell.py", line 828, in __Make_Menu_Area
l = inspect.getmembers(eval(c))
What happened in lines 1 through 22? My guess would be
just import inspect


and after that .... QUID ?

Thanks and regards,

Philippe





Peter said:
Philippe said:
l = inspect.getmembers(eval('BC')) #THIS CRASHES - the class exists

Care to provide the traceback?
In [23]:from SC.CARDS.BC import *

In [24]:l = inspect.getmembers(eval('BC'))

What happened in lines 1 through 22? My guess would be

In [13]:from SC.CARDS import *

Be that as is may, eval("BC") can be simplified to BC,

from module import *

is the last roadhouse en route to chaos and an unqualified

try ... except

shows you are willing to drive with defunct brakes. By introducing exec
and eval() you are throwing the steering wheel out of the window.

Seriously, try to make do with __import__() and getattr() to clean up
your code a bit.

Driving-analogies-well-beyond-the-abyss-ly yours
Peter
 
P

Peter Otten

Philippe said:
OK Peter, first of all thanks.

You seem to be German and although I leave in the states, I'm French and
your english is clearly far more advanced than mine: I have yet to
understand a few of your comments ;-)

My French is mostly read-only, so let me rephrase:

from module import *, try ... except, eval(), exec all work together to make
your program harder to understand and more likely to fail in obscure ways.
Traceback (most recent call last):
File "SC_Shell.py", line 1095, in ?
l_d = SC_Shell()
File "SC_Shell.py", line 326, in __init__
self.__Make_Menu_Area()
File "SC_Shell.py", line 828, in __Make_Menu_Area
l = inspect.getmembers(eval(c))
File "<string>", line 0, in ?
NameError: name 'BC' is not defined

That traceback and the code you posted do not fit together. So back to
square one.

Staring at the code you posted, I think one thing you could try would be to
modify the eval() to

eval("BC", self.m_process_global, self.m_process_local)

to ensure that eval() and exec share the same namespace.
Generally speaking, I would prefer (I hope I got that right)

module = __import__("package.module", globals(), locals(), ["module"])
members = inspect.getmembers(module)

Members of the module would then be accessed via getattr():

member = getattr(module, member_name)

Peter
 
P

Peter Otten

Philippe said:
Any clue would be quite welcome.

I didn't recognize the pattern in the code you posted, but sometimes the
order of imports matters:

$ find .
..
../package
../package/beta.py
../package/alpha.py
../package/__init__.py
$ python
Python 2.3.3 (#1, Feb 5 2005, 16:22:10)
[GCC 3.3.3 (SuSE Linux)] on linux2
Type "help", "copyright", "credits" or "license" for more information.Traceback (most recent call last):
<module 'package.beta' from 'package/beta.py'>

The 'right' way to do the imports if you want both 'alpha' and 'beta' is of
course

from package import alpha
from package import beta

Peter
 
P

Philippe C. Martin

My French is mostly read-only, so let me rephrase:
Thank you :)
from module import *, try ... except, eval(), exec all work together to
make your program harder to understand and more likely to fail in obscure
ways.
What would you suggest then, I just want my code to
1) be sturdy
2) some of the modules might not be there depending on the configuration,
and I want their members in the menus if they are installed.

If there is a cleaner way, I'm ready to try it.

eval("BC", self.m_process_global, self.m_process_local)

to ensure that eval() and exec share the same namespace.
Generally speaking, I would prefer (I hope I got that right)

That was it, thank you!
module = __import__("package.module", globals(), locals(), ["module"])
members = inspect.getmembers(module)

Members of the module would then be accessed via getattr():

member = getattr(module, member_name)
I will study that.


Many thanks

Philippe



Peter said:
Philippe said:
OK Peter, first of all thanks.

You seem to be German and although I leave in the states, I'm French and
your english is clearly far more advanced than mine: I have yet to
understand a few of your comments ;-)

My French is mostly read-only, so let me rephrase:

from module import *, try ... except, eval(), exec all work together to
make your program harder to understand and more likely to fail in obscure
ways.
Traceback (most recent call last):
File "SC_Shell.py", line 1095, in ?
l_d = SC_Shell()
File "SC_Shell.py", line 326, in __init__
self.__Make_Menu_Area()
File "SC_Shell.py", line 828, in __Make_Menu_Area
l = inspect.getmembers(eval(c))
File "<string>", line 0, in ?
NameError: name 'BC' is not defined

That traceback and the code you posted do not fit together. So back to
square one.

Staring at the code you posted, I think one thing you could try would be
to modify the eval() to

eval("BC", self.m_process_global, self.m_process_local)

to ensure that eval() and exec share the same namespace.
Generally speaking, I would prefer (I hope I got that right)

module = __import__("package.module", globals(), locals(), ["module"])
members = inspect.getmembers(module)

Members of the module would then be accessed via getattr():

member = getattr(module, member_name)

Peter
 

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

Members online

Forum statistics

Threads
474,260
Messages
2,571,301
Members
47,944
Latest member
LillianPra

Latest Threads

Top