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. |