|
From: <bc...@wo...> - 2000-11-19 14:06:22
|
[Samuele Pedroni]
>Hi.
>
>[Finn]
>> My *intention* for moduleInitDict was as a general hook which any java
>> class could implement if it wanted some control over its __dict__ when
>> it is imported. It was not only for compiled modules.
>For that we have classInitDict, which invocation seems to me in the right
>place.
>Clearly classDictInit is ok for manipulating the __dict__ but should not run
>a module main.
>Why the InitModule and his support code are still left around?
>Should we clean that?
I have not removed it in the small hope that 3rd part modules which uses
InitModule would continue to run with jython. I have not tested this, so
this kind of compatibility may have been broken by some other change.
>> So all together, your suggestion sounds better.
>I think we should put such code that deal with $_PyInner classes
>in loadBuiltin and loadFromPath. ((The builtins coming from compilation
> exceptions and cPickle_exc ... should then be better recompiled)).
>But then I imagine that a user would expect to be able to put
>a jar containing compiled modules in classpath and be able
>to import them. The simplest straightforward impl
>will not offer that, limiting the search of $_PyInner classes
>to sys.path as for .py and $py.class files.
Right.
>I do not know if can offer the latter with a clean semantics,
>but we can use for that openResourceAsStream.
>I'm also asking myself if we should consider the dynamic value
>of __path__ when looking for $_PyInner modules or not.
>(( Maybe all that is related to the big design question, wheter we want
>to load .py($py.class) also from classpath and have jars
>on sys.path... ))
>Notice that with this design choice if someone load a compiled
>module through a java package it will get simply the java class
>not the module, for me this makes sense
I fear it will be FAQ. In some setups you will get the module, in others
you will get the proxy. They have the same name so it is not obvious
which you happened to import.
>but then we remain
>with the problem of how to enable the usage of compiled py classes
>as java classes from jython.
I would not mind too much if the generated proxy classes wasn't
available from jython at all. As long as the module and all the classes
inside the module are available.
>You have always declared that this
>is really difficult and I should admit that I have not studied it yet,
>can you list what are the serious problem with that?
One problem that I have looked at is the way proxies stop their search
for attributes when they meet their first java superclass. As a result
subclasses of proxies can not find methods in the superclass and
overriding does not work:
------ x.py ------
import java
class x(java.lang.Object):
def equals(self, other):
print "equals", self, other
return 0
------ END ------
Compile the x.py module to java class x.java.
>>> import x
>>> print type(x)
org.python.core.PyJavaClass
>>> a = x()
>>> print a
x@682b72
>>> print a.equals(a), a.equals(x)
1 0
>>>
>> Still, I feel a link is missing. Some way to go from x.class to
>> x$_PyInner.class, maybe as some public API in imp.java or Py.java.
>Sorry, I do not understand what you mean with that.
I was thinking about the case where x.class and x$_PyInner.class exist
in a java package. A call to imp.load("x") will get the x.class, but
what if the programmer wanted the x.py module. Basicly the same problem
you described above.
Hmmm....
I think we should load the x.class when found in a java package. We can
decide if we should change this when we get more feedback from users.
So loadBuiltin and loadFromPath should look for $_PyInner as the last
option.
regards,
finn
BTW, the exceptions.java and cPickle_exceptions modules are just a
temporary hack. And so should the loadBuiltin be IMO. I have included an
old email where I try to describe the reasoning for the hack:
Subject: [Jython-dev] builtin exceptions
From: bc...@wo... (Finn Bock)
Date: Sat, 30 Sep 2000 19:32:09 GMT
Hi,
There is a problem with the exceptions module. At least there is if we
want to follow CPython's route where:
- string based std. exception are dropped.
- the exceptions module is builtin.
I think we want both. And when there no longer are string based std
exception as a fall back, we must be very certain that the exceptions
module can be loaded. So we also want to make it a builtin module.
I'd tried different experiments in the erratas. First I coded the
exceptions module as java class:
package org.python.modules;
public class exceptions {
public static class Exception extends PyObject {
public static String __doc__ =
"Base class for all standard Python exceptions.";
public PyTuple args = Py.EmptyTuple;
public Exception() {
}
public Exception(PyObject[] args, String[] kws) {
this.args = new PyTuple(args);
}
public PyString __str__() {
switch (args.__len__()) {
case 0:
return Py.newString("");
case 1:
return args.__getitem__(0).__str__();
default:
return args.__str__();
}
}
...
}
Initially this worked like a charm. From python this type can be
extended as usual and from java it can be extended as
public static class PickleError extends exceptions.Exception {
public PickleError() { }
public PickleError(PyObject[] args, String[] kws) {
super(args, kws);
}
public PyString __str__() {
if (args.__len__() > 0 && args.__getitem__(0).__len__() > 0)
return args.__getitem__(0).__str__();
else
return new PyString("(what)");
}
}
It does have some problems:
1) type(Exception) return TypeType, not ClassType
2) A java class does not allow changes to its __name__, nor can it
control how it will be represented by str() and repr(). (Instances
of a java class can control it's representation, but the class
itself can't).
3) A python class will not be able to inherit from two such exceptions.
Based on the experience, I decided to give up on exceptions.java and
instead built the exceptions module as a java class which create the
python classes by hand. Just like the exceptions.c does.
Unfortunately JPython have no API designed for this. The only way you
can create a python class is the jpythonc (and the dynamic code
compiler) creates python classes. That API (PyTableCode) is best suited
for mechanical code generation.
So in the latest errata I used jpythonc on exceptions.py, made it create
the file org/python/modules/exceptions.java and included this class in
the jar file.
Yes, it's Bad (tm).
We have to design a human usable API with which a programmer can create
python classes and populate it with functions and attributes. I just
fear that it isn't achievable before the first alpha.
Our short term options are, as I see them:
1) Keep exceptions.py *and* use string based std exception as a
fallback. I'll hate that because it makes it difficult to
create modules that must work with both string based and class
based exceptions.
2) Keep exceptions.py *without* any fallback if exceptions.py fail
to load.
3) Include the generated exceptions.java (and the similarly generated
cPickle_exceptions.java).
I favor number 3.
|