metaclasses and Exceptions

M

Mark Nottingham

From previous discussion [1] it seems that it's not possible to raise
new-style objects. Does this effectively mean that it's impossible to
use anything with a metaclass as an exception? i.e., am I missing some
nifty trick that would allow me to do this in the meantime?

If not, does anyone anticipate this changing anytime soon?

Cheers and thanks,

1. http://aspn.activestate.com/ASPN/Mail/Message/python-list/1095990
 
A

Aahz

From previous discussion [1] it seems that it's not possible to raise
new-style objects. Does this effectively mean that it's impossible to
use anything with a metaclass as an exception? i.e., am I missing some
nifty trick that would allow me to do this in the meantime?

Why do you want to do this?
If not, does anyone anticipate this changing anytime soon?

Python 3.0
--
Aahz ([email protected]) <*> http://www.pythoncraft.com/

"To me vi is Zen. To use vi is to practice zen. Every command is a
koan. Profound to the user, unintelligible to the uninitiated. You
discover truth everytime you use it." (e-mail address removed)
 
M

Michael Hudson

From previous discussion [1] it seems that it's not possible to raise
new-style objects. Does this effectively mean that it's impossible to
use anything with a metaclass as an exception?
Yes.

If not, does anyone anticipate this changing anytime soon?

One of the areas where PyPy is different from CPython is that there
are no old-style classes or instances, so exceptions are necessarily
new-style. This has caused no real problems on any Python program
we've tried it on yet...

Cheers,
mwh
 
M

Mark Nottingham

From previous discussion [1] it seems that it's not possible to raise
new-style objects. Does this effectively mean that it's impossible to
use anything with a metaclass as an exception? i.e., am I missing some
nifty trick that would allow me to do this in the meantime?

Why do you want to do this?

I have to define a fairly large number (~40) of exceptions, and need
to keep a dictionary keyed on an error code for each, so that the
appropriate exception can be looked up. While I can manage it
manually, it would be much cleaner and more reliable to use a
metaclass to automatically create the dictionary from class
attributes.

E.g.,

class MyExceptionNumberOne:
code = "1"

class MyExceptionNumberTwo:
code = "2"

lookup = {
1: MyExceptionNumberOne,
2: MyExceptionNumberTwo,
}

Cheers,
 
?

=?iso-8859-1?Q?Fran=E7ois?= Pinard

[Mark Nottingham]
I have to define a fairly large number (~40) of exceptions, and
need to keep a dictionary keyed on an error code for each, so that
the appropriate exception can be looked up. While I can manage
it manually, it would be much cleaner and more reliable to use
a metaclass to automatically create the dictionary from class
attributes.

Yes, it is a bit annoying that exceptions are not types. However, what
you could do with metaclasses for building a registry of exceptions,
you could achieve with module introspection. Here is some example code:


---------------------------------------------------------------------->
class Erreur(Exception):
diagnostic = "Erreur Pyam"

def __str__(self):
if self.args:
return self.diagnostic + ': ' + ', '.join(map(str, self.args))
return self.diagnostic

class ErreurDenotation(Erreur):
diagnostic = "Dénotation invalide"

# [etc.]

def fabriquer_erreur_selon_nom():
# J'aurais bien voulu donner une méta-classe à Erreur pour fabriquer le
# registre au vol, mais une classe dérivée de Exception _doit_ être une
# ancienne classe, pour des raisons techniques internes à Python.
from types import ClassType
for nom, valeur in globals().iteritems():
if isinstance(valeur, ClassType) and issubclass(valeur, Erreur):
erreur_selon_nom[nom] = valeur

erreur_selon_nom = {}
fabriquer_erreur_selon_nom()
----------------------------------------------------------------------<
 
R

Raymond Hettinger

Michael Hudson said:
are no old-style classes or instances, so exceptions are necessarily
new-style. This has caused no real problems on any Python program
we've tried it on yet...

How does PyPy distinguish between instance and class arguments to
raise?

Given: raise X
Does it pass X or X()?


Raymond Hettinger
 
M

Michael Hudson

How does PyPy distinguish between instance and class arguments to
raise?

"isinstance(x, type)", iirc.

The code is in this file:

http://codespeak.net/svn/pypy/trunk/src/pypy/interpreter/pyframe.py

in the function app_normalize_exception(). There's a kind of horrible
issue if you do things like:

class Nasty(type, Exception):
pass

raise Nasty()

I can't remember what PyPy does here (the answer is quite possibly
"break").
Given: raise X
Does it pass X or X()?

Depends on X! Has to, really, or we certainly would have had more
problems from this than we've had.

Cheers,
mwh
 

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
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top