[Patches] [ python-Patches-448488 ] Implemenation of ImportNotFoundError PEP
noreply@sourceforge.net
noreply@sourceforge.net
Tue, 25 Sep 2001 17:39:42 -0700
Patches item #448488, was opened at 2001-08-06 11:51
You can respond by visiting:
http://sourceforge.net/tracker/?func=detail&atid=305470&aid=448488&group_id=5470
Category: Core (C code)
Group: None
Status: Closed
Resolution: Rejected
Priority: 5
Submitted By: Frederic Giacometti (giacometti)
Assigned to: Nobody/Anonymous (nobody)
Summary: Implemenation of ImportNotFoundError PEP
Initial Comment:
This is a reference implementation for the PEP proposal.
Here, the patch has existed before the PEP, therefore the PEP refers to the patch...
I need to create the patch before I submit the PEP :)))
Frederic Giacometti
-----------------------
PEP XXX: ImportNotFoundError Exception
fred@arakne.com (Frederic Giacometti)
Abstract
The object of this proposal is the definition of a specific
ImportNotFoundError error, along with its association to a new
import exception trapping mechanism
that will enable the extension of the import mechanism to generic global/static
objects.
Part 1: The ImportNotFoundError exception.
In the present code, the ImportError string exception
is used for all import failures; this does not permit us to catch efficiently
import failures caused specifically by a 'component not found' situation.
To fix this, we introduce a new exception, that we call ImportNotFoundError.
This exception is designed for use in the very specific situation where
an import string cannot be found by the import mechanism (as opposed to 'found'
but 'failed to open', failed to load', 'failed to initialize'...).
ImportNotFoundError instance raised within execution of
an import statement will have two attributes as follows:
- 'parent': the element of sys.modules where the next import failed,
or None if top-level import.
- 'name': the string of the next .-separated component which failed
A formal Python definition of ImportErrorNotFound could be:
class ImportNotFoundError( ImportError):
def __init__( self, parent, name):
assert( hasattr( parent, '__name__'))
assert( sys.modules.has_key( parent.__name__))
assert( sys.modules[ parent.__name__] is parent)
assert( not hasattr( parent, name))
ImportError.__init__( self, parent, name)
self.parent = parent
self.name = name
2) Alternative import customization hook in the module global scope
(__altimp__)
2.a: Why in the module global scope?
(or: Why not overwrite builtins.__import__?)
Use of builtins.__import__ is not a preferred integration practice: Only
one __import__ value can be defined; and if you're integrating two components
with each its own __import__ version, you'll be stuck...
Furthermore, if one insists on overwriting __import__, one can still do it.
Meanwhile, if an application requires overwriting __import__,
and one does not want to, one is stuck again...
Since we want to keep options open, we're proposing to enhance
the import procedure defining a trapping mechanism
based on the presence of a globals()[ '__altimp__'] object, which is called
if present upon trigger of an ImportNotFoundError within an import statement.
In doing so, those who don't want (rightfully) to be bothered won't be,
unless they define __altimp__ in their module global scope, and a module's
usage of a certain implementation of __altimp__ won't bother other modules,
at all.
2.b Definition
If present, globals()[ '__altimp__'] will refer to a callable object specified
as follows:
def importextended( failedparent, failedname, name,
globs=None, locs=None, fromlist=None):
failedparent: 'parent' attribute from the ImportnotFoundError exception
failedname: 'name' attribute from the ImportnotFoundError exception
(name, globs, locs, fromlist): same arguments as in __import__()
return: same as in __import__() [object for insertion in sys.modules...]
Effect on existing code
There should be no effect on existing code, other than when code like
exc.__class__ == ImportError
has been meant for
isinstance( exc, ImportError)
(hopeless anyway? :(()
Applications:
Given that importext.py contains:
__all__ = ('importextended')
import sys
def importextended( failedparent, failedname, name,
globs=None, locs=None, fromlist=None):
curmod = failedparent
remainder = name[ len( curmod.__name__) + 1:].split( '.')
while remainder:
curname = remainder.pop( 0)
curmod = getattr( curmod, curname)
sys.modules[ curmod.__name__] = curmod
return curmod
A JPE file may contain:
# import Java's javax.swing package in global scope
from importext import importextended as __altimport__
from java import Jstring
from java.system.javax import swing
frame = swing.JFrame( Jstring( 'HelloWorldSwing'))
label = swing.JLabel( Jstring( 'Hello World'))
frame.getContentPane().add(label)
frame.setDefaultCloseOperation( swing.JFrame.EXIT_ON_CLOSE)
frame.pack()
frame.setVisible( 1)
A Metadynamic Python file can contain:
# User is a Metaphase persistant class
from importext import importextended as __altimport__
from metadyn.mclass import User
users = mclass.User.QueryDbItem( some_query)
...
Based on this feature, applications can easily be programmed
on the client side for any client/server situation,
including pulling Python modules from remote repository...
Reference Implementation:
A sample implementation of ImportErrorNotFoundError
in the current import mechanism, with
the __altimp__ hook is provided in patch href:attached_file.
----------------------------------------------------------------------
>Comment By: Frederic Giacometti (giacometti)
Date: 2001-09-25 17:39
Message:
Logged In: YES
user_id=93657
How?
You could at least give a pointer, a word, something!
FG
----------------------------------------------------------------------
Comment By: Guido van Rossum (gvanrossum)
Date: 2001-09-25 17:32
Message:
Logged In: YES
user_id=6380
The existing import hooks have ways to do this without
catching the exception.
----------------------------------------------------------------------
Comment By: Frederic Giacometti (giacometti)
Date: 2001-09-25 17:18
Message:
Logged In: YES
user_id=93657
There are two application scenarios for __altimp__, and the
__altimp__ implementation requires ImportNotFoundError.
The introduction of ImportNotFoundError is the only way I
could find to implement efficiently __altimp__ .
I'm giving below an similar implementation in Python that
overrides __import__ (with the inconvenient that this
affects all import statements).
A possible importextended function is defined in the
[sample] 'Application' section of the PEP :
------------
pyimport = __import__
def altimport( name, globs=None, locs=None, fromlist=None):
try:
return pyimport( globs, locs, fromlist)
except ImportNotFoundError, iexc:
return importextended( iexc.parent, iexc.name, name,
globs, locs, fromlist)
sys.__buildins__.__import__ = altimport
----------------------
Let's make clear that in this case I only want to catch the
ImportError's corresponding to something whose import fails
because it is not on the filesystem (not on PYTHONPATH....),
and that I do not want to catch any other case of
ImportError that could be raised.
Thus, a subclass of ImportError is needed:
ImportNotFoundError.
FG
----------------------------------------------------------------------
Comment By: Guido van Rossum (gvanrossum)
Date: 2001-09-25 16:39
Message:
Logged In: YES
user_id=6380
What's missing is why an application would need to catch
this kind of import failures. I have a limited imagination,
and I can't come up with a scenario that would require this.
That's what I meant by "motivation".
----------------------------------------------------------------------
Comment By: Frederic Giacometti (giacometti)
Date: 2001-09-25 15:11
Message:
Logged In: YES
user_id=93657
The 'motivation' is at the beginning of the first section of
the PEP. I'm pasting it below:
Part 1: The ImportNotFoundError exception.
In the present code, the ImportError
string exception
is used for all import failures; this
does not permit us to catch efficiently
import failures caused specifically by
a 'component not found' situation.
To fix this, we introduce a new
exception, that we call ImportNotFoundError.
This exception is designed for use in
the very specific situation where
an import string cannot be found by the
import mechanism (as opposed to 'found'
but 'failed to open', failed to load',
'failed to initialize'...).
----------------------------------------------------------------------
Comment By: Guido van Rossum (gvanrossum)
Date: 2001-09-25 06:36
Message:
Logged In: YES
user_id=6380
Rejected. The "PEP" doesn't provide a motivation for the
ImportNotFound error, and I don't see a reason why this
particular condition should be excepted.
The __altimp__ idea is a nice one, but the elaboration here
is incomprehensible. I suggest that you submit this idea as
a separate patch.
----------------------------------------------------------------------
Comment By: Martin v. Löwis (loewis)
Date: 2001-08-07 21:54
Message:
Logged In: YES
user_id=21627
There is in general no need to put the PEP into the SF
comment. Just send it to the PEP editor, who should assign
a PEP number and commit it into CVS in a timely manner.
I have a number of comments on this PEP, but I'll send
them directly to you once the PEP is on python.sf.net/peps.
----------------------------------------------------------------------
You can respond by visiting:
http://sourceforge.net/tracker/?func=detail&atid=305470&aid=448488&group_id=5470