This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: ae* modules: handle type inheritance
Type: Stage:
Components: macOS Versions: Python 2.3
process
Status: closed Resolution: accepted
Dependencies: Superseder:
Assigned To: jackjansen Nosy List: dsposx, jackjansen, loewis
Priority: normal Keywords: patch

Created on 2002-04-02 19:24 by dsposx, last changed 2022-04-10 16:05 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
aesuperclass.diff dsposx, 2002-04-02 19:24
aesuperclassnew.diff dsposx, 2002-05-02 20:47 Functionality updated using Jack's suggestions.
Messages (9)
msg39447 - (view) Author: Donovan Preston (dsposx) Date: 2002-04-02 19:24
The gensuitemodule script creates Python 
classes out of AppleScript types. It keeps track of 
properties in _propdict and elements in _elemdict. 
However, gensuitemodule does not accurately 
replicate the AppleScript inheritance heirarchy, and 
__getattr__ only looks in self._propdict and 
self._elemdict, therefore not finding elements and 
properties defined in superclasses.

Attached is a patch which:

1) Correctly identifies an AppleScript type's 
superclasses, and defines the Python classes 
with these superclasses. Since not all names may 
be defined by the time a new class is defined, this 
is accomplished by setting a new class' 
__bases__ after all names are defined.

2) Changes __getattr__ to recurse superclasses 
while looking through _propdict and _elemdict.

It also contains small usability enhancements 
which will automatically look for a .want or .which 
property when you are creating specifiers.
msg39448 - (view) Author: Jack Jansen (jackjansen) * (Python committer) Date: 2002-04-02 21:47
Logged In: YES 
user_id=45365

Donovan, I love the functionality of your patch, but I would humbly request you make a couple of changes. Alternatively I'll make them, but that will delay the patch (as I have to find the time to do them).

First: please make it a context diff (cvs diff -c), as straight diffs are too error prone for moving targets. There are also mods I can't judge this way (such as why you moved the 'utxt' support in aepack.py to a different place. Or is this a whitespace mismatch?)

Second: you've diffed against the different version than against which you've patched. See gensuitemodule, for instance: it appears as if you've modified 1.22 but diffed against 1.21. Maybe you applied my 1.21->1.22 by hand without doing a cvs update? I think a cvs update (plus some manual work;-) should solve this.

Third: the passing of modules by name (to the decoding routines) seems error prone and not too elegant. Can't you pass the modules themselves in stead of their names? It would also save extra imports in the decoders.

Fourth: assigning to __bases__ seems like rather a big hack. Can't we generate the classes with a helper class, similarly to the event helper class in the __init__.py modules: FooApp/Foo_Suite.py would contain the class foo sketched above, and FooApp.__init__.py would contain
import othersuite.superfoo
import Foo_Suite.foo
class foo(Foo_Suite.foo, othersuite.superfoo):
	pass

Fifth, and least important: you're manually iterating over the base classes for lookup. Couldn't we statically combine the _propdict and _elemdict's of the base classes during class declaration, so that at lookup time we'd need only a single dictionary lookup? The "class foo" body in __init__.py would then become something like
	_propdict = aetools.flatten_dicts(
		foosuite.foo._propdict,
		othersuite.superfoo._propdict)
and similar for elemdict.
msg39449 - (view) Author: Donovan Preston (dsposx) Date: 2002-04-03 06:50
Logged In: YES 
user_id=111050

Jack:

Thanks a lot for your comments! You're right on target on most of them.

Not sure why I didn't make a context diff this time -- last time it was screwed up, I thought it was because of that, but it was really just the tabs vs spaces issue. cvs is still very new and ugly to me.

I did indeed manually apply your patches to my tree, because I was afraid of what an update would do to the production code that my boss would kill me if broke... I'll do an update on another machine and reapply the patches to that checkout. Is there any way I can get a log of what the update has done to my files, so I can check them manually?

Hmm. I hadn't thought about passing the module itself; how would I get a reference to a package from inside of that package's __init__.py? From aetools, I can get away with saying __import__(modulename), but inside of __init__.py, what do I use to get a reference to the module that __init__.py is initializing?

Finally, after thinking about it a bit, Fourth and fifth points may be better solved by a construct like this:

(applescript type bar inherits from foo)

bar._elemdict = copy(foo._elemdict)
bar._elemdict.update({ dict of new keyword/class mappings })

This has the advantage of flattening out the inheritance tree again, since all elements and properties each class needs to know about are in it's own copy of _elemdict and _propdict, and therefore no Python inheritance relationship needs to be made.

I had wanted to build the inheritance heirarchy properly, and dynamically look through bases, because it was "cool" but in retrospect, speed is more important :-)

Donovan
msg39450 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2002-04-03 09:29
Logged In: YES 
user_id=21627

cvs update will keep a copy of the original file (the one
you edited) if it has to merge changes; it will name it
.#<file>.<version>. So in no case cvs will destroy your
changes. Normally, merging works quite well. If it finds a
conflict, it will print a 'C' on update, and put a conflict
marker in the file. The stuff above the ===== is your code,
the one below is the CVS code.

If you want to find out what cvs would do, use 'cvs status'.

If you don't want cvs to do merging, the following procedure
will work

cvs diff -u >patches
patch -p0 -R <patches
cvs up
patch -p0 <patches

Notice that the last patch may report rejected hunks in case
of conflicts.
msg39451 - (view) Author: Jack Jansen (jackjansen) * (Python committer) Date: 2002-04-03 21:16
Logged In: YES 
user_id=45365

Donovan, two comments-on-your-comments:
- You're absolutely right about the module names. Pickle also uses names, and it's probably the only way to do it.
- You're also absolutely right about how to update the _elemdict and _propdict.

Or, as Jean-Luc Picard would say: "Make it so!" :-)

Oh yes, on the production code/merging problem: aside from Martin's comments here's another tip: make a copy of the subtree that contains the conflict section (why not the whole Mac subtree in your case) and make sure you keep the CVS directories. Start hacking in this copy. Once you're satisfied do a commit from there. As long as you keep the CVS directory with the files there's little that can go wrong.
msg39452 - (view) Author: Donovan Preston (dsposx) Date: 2002-05-02 20:47
Logged In: YES 
user_id=111050

Hi Jack,

I finally got around to reimplementing the functionality of 
the patch given your suggestions. I think it should be 
fairly bulletproof. Due to circular imports I ended up 
having to do more work in the package's __init__.py. 
The upshot of flattening the lookup dicts is that it gets 
done once, and then after that name lookups are 
lightning fast. In our production environment the 
speedup was impressive :-) Thanks for the 
suggestions.

Donovan
msg39453 - (view) Author: Jack Jansen (jackjansen) * (Python committer) Date: 2002-05-24 15:21
Logged In: YES 
user_id=45365

Donovan,
I finally got started with your patch. Two more questions, just to make sure I understand things:
- You've changed the way the resource file is opened (in gensuitemodule, processfile(). Why?
- The getbaseclasses() function you generate seems prety static. Couldn't it be declared in aetools? Or maybe even be a class method of aetools.TalkTo?

Don't bother fixing the patch, just let me know the answers and I'll hack it myself.

(And, out of curiosity, where did you find info on the funny properties such as "c@#^"? I've never managed to find anything...)
msg39454 - (view) Author: Donovan Preston (dsposx) Date: 2002-06-23 16:55
Logged In: YES 
user_id=111050

Jack,

Great, thanks for looking at it again. I'm not sure why I
never got email with your follow up. I guess sourceforge
screwed up?

In processfile, I changed the way the resource file is
opened because I am running gensuitemodule under
Mach-oPython. I believe CurResFile wasn't working for me;
switching to macresource.need worked for me but there is one
problem: If you run gensuitemodule on one application, it's
resource file will be opened but never closed. If you then
attempt to run gensuitemodule on another application in the
same process, you will generate a suite module for the first
application (But everything will be named for the second
application!). If opening and closing the resource file is
the right thing to do and you can get those calls to work
under Mach-oPython, that would be preferrable.

getbaseclasses could be declared in aetools or on
aetools.TalkTo, whatever you think is appropriate.

Sorry I hadn't followed up earlier, I have been very busy
and only decided to check the status of the patch today on a
whim!

Oh, and I never found any information about the 'c@#^'
property, I just put in print statements in the right places
to observe what was going on, and deduced what it was.

Donovan
msg39455 - (view) Author: Jack Jansen (jackjansen) * (Python committer) Date: 2002-08-09 14:26
Logged In: YES 
user_id=45365

Donovan,
I checked your mods in, with the following changes:
- I had to massage getbaseclasses() a bit
- I replaced your aetypes.beginning() and end() by something
  a bit more in line with the rest of the module
- I removed your macresource.open_file mods.

If you still feel the latter are needed (I don't seem to need them) please file a separate bug report. If you find any issues with the other stuff please let me know asap.
History
Date User Action Args
2022-04-10 16:05:11adminsetgithub: 36370
2002-04-02 19:24:39dsposxcreate