From: Nikola Skoric on
Dana Fri, 18 Jun 2010 20:01:45 +0200,
Peter Otten <__peter__(a)web.de> kaze:
> Solution: move your startup code into a separate file and have it import the
> village module.

Excellent, thanks! Everything works now, but I still don't quite get what the problem is...

> You are importing your main script elswhere. Your code then
> effectively becomes
>
> try:
> # in another module
> raise village.SomethingBuiltError
> except __main__.SomethingBeingBuiltError:
> print "caught"
>
> i. e. you get two versions of every class that are built from the same code
> but not (recognized as) identical.

What I don't get is: what do you mean I'm importing my main script
elsewhere by runing "python village.py"? SomethingBuiltError is
defined in the same script that I'm runing, I didn't import it, did I?
If you could please clear it up for me... or point me to relevant
literature, that's also cool, I couldn't find this thing explained
anywhere.

Anyway, thanks for the solution!

--
"Now the storm has passed over me
I'm left to drift on a dead calm sea
And watch her forever through the cracks in the beams
Nailed across the doorways of the bedrooms of my dreams"
From: Nikola Skoric on
Dana 18 Jun 2010 17:45:31 GMT,
Steven D'Aprano <steve(a)REMOVE-THIS-cybersource.com.au> kaze:
> Other than that, I notice that your module throws away useful debugging
> information, and replaces it with bland, useless pap of no nutritional
> value:
>
> try:
> import account, fetch, resources, const
> except Exception:
> raise Exception('One or more travapi modules not available.')

Oh, yes, thanks for pointing that out, that was a dirty hack for
solving some error I was getting with pydoc. I'll remove that, thanks
for pointing that out.

--
"Now the storm has passed over me
I'm left to drift on a dead calm sea
And watch her forever through the cracks in the beams
Nailed across the doorways of the bedrooms of my dreams"
From: Peter Otten on
Nikola Skoric wrote:

> Dana Fri, 18 Jun 2010 20:01:45 +0200,
> Peter Otten <__peter__(a)web.de> kaze:
>> Solution: move your startup code into a separate file and have it import
>> the village module.
>
> Excellent, thanks! Everything works now, but I still don't quite get what
> the problem is...
>
>> You are importing your main script elswhere. Your code then
>> effectively becomes
>>
>> try:
>> # in another module
>> raise village.SomethingBuiltError
>> except __main__.SomethingBeingBuiltError:
>> print "caught"
>>
>> i. e. you get two versions of every class that are built from the same
>> code but not (recognized as) identical.
>
> What I don't get is: what do you mean I'm importing my main script
> elsewhere by runing "python village.py"? SomethingBuiltError is
> defined in the same script that I'm runing, I didn't import it, did I?
> If you could please clear it up for me... or point me to relevant
> literature, that's also cool, I couldn't find this thing explained
> anywhere.

In Python, if you write

class A:
pass

that is executable code just like an if-statement or a for-loop rather than
a declaration, and this code creates a new class every time it is run.
That's why

>>> items = []
>>> for i in range(5):
.... class A: pass
.... items.append(A)
....
>>> issubclass(A, A)
True
>>> issubclass(items[0], items[1])
False

creates 5 distinct classes. The same would go for modules if it weren't for
the sys.modules cache:

>>> open("tmp.py", "w").write("print 'importing', __name__\n")
>>> import tmp
importing tmp
>>> import tmp # module is looked up in cache, code not run

If we clear the cache manually, the code in the module will be executed
again:

>>> import sys
>>> del sys.modules["tmp"]
>>> import tmp
importing tmp

Now in your case village.py is first run as the main script and then
imported from within account.py -- but the main script is put into the cache
under the key "__main__" regardless of its actual name. Using our simple
example:

$ python -i tmp.py
importing __main__
>>> import tmp
importing tmp

So you end up with a __main__ module and a village module that contain
functions and classes built from the same code but with distinct identities.

In the account module you indirectly raise village.ExceptionWithLongName and
in __main__ you try to catch __main__.ExceptionWithLongName.

Peter
From: Nikola Skoric on
Dana Sun, 20 Jun 2010 10:53:08 +0200,
Peter Otten <__peter__(a)web.de> kaze:
> Now in your case village.py is first run as the main script and then
[...]
> In the account module you indirectly raise village.ExceptionWithLongName and
> in __main__ you try to catch __main__.ExceptionWithLongName.

Phew. I get it now. You're my hero :-D I had to read it twice, but I
got it. Thanks a bunch!

--
"Now the storm has passed over me
I'm left to drift on a dead calm sea
And watch her forever through the cracks in the beams
Nailed across the doorways of the bedrooms of my dreams"