[PYTHONMAC-SIG] Some ideas for Mac Python

Jack Jansen Jack.Jansen@cwi.nl
Wed, 31 Jan 1996 02:36:50 +0100


This is going to be a long reply to a long message (especially since
it tackles almost all of the issues in the charter:-). Maybe we should
split the discussion into multiple parts?

Non-C-hackers: please bear with me, there's some design issues
in here as well that I would welcome discussion on.

Recently, Guido van Rossum <guido@CNRI.Reston.VA.US> said:
> Here are some areas where I think MacPython can use some improvement.
> 
> 1) CFM-68K support.  This is shared libraries, PPC style, for the
>    68K.

Guido: the miniPythonCFM68K project in the source tree appeared to
work under CW7.5 (with the exception of the math module), so that
would probably be a good starting point. Others: if anyone is
interested in looking into cfm68k: drop me a note and I'll put the
project up for ftp.

> 2) GUSI support.

Yes, this would definitely be nice, especially since it would probably
make the MacTk integration quite a bit easier. The #include <GUSI.h>
isn't a problem: put it in the prefix file
(mwerks_whatever_config.h). If you (or anyone else) is going to look
into it: make sure you check that os.stat() still works as expected
afterwards. I had problems with GUSI stat().

> 3) Tk.

Definitely! One serious problem with Tk, though, is that it expects
malloc to succeed. Always. There is no code whatsoever that checks
return values, so tkpython programs running out of memory will have
extremely rude things done to them (along the lines of "nobody expects
the spanish inquisition":-).

> 4) Configure some Mac specific hacks dynamically (at run-time) instead
>    of through #ifdefs.

Yes. I've already created a Python library (similar to PythonCore but
as a static library) that I used in my first experimentations with
Netscape extensions. Hmm, speaking of that: is anyone willing to take
over the work on a python-interpreter netscape extension?

>    a) Program argument processing.

This is fairly simple to fix, by moving the init_mac_stuff() routine
to another place and using a different main program that doesn't call
the argc/argv emulation routine. There's a related problem, though:
the Py_Exit() call in core-python is better split in two:
Py_JustBeforeExit() and Py_Exit(). In some cases (such as a netscape
extension) you want to do all of the exit processing *except*
exiting.

>    b) Event checking.  There is some code that normally checks for
>       Command-period (turning it into a KeyboardInterrupt exception)
>       but which can be disabled; it can optionally also check for
>       other events, passing them to SIOUX (the CodeWarrior stdio
>       window) or stdwin or elsewhere.  I think this should probably be
>       done in such a way that even in order to enable Command-period
>       checking the main program would have to register some kind of
>       callback (even though the callback function could be part of the
>       standard library).  (Of course this interface should still be
>       accessible from Python code, so Framework.py can take care of
>       its own needs.)

Hmm, not sure I like this one. The callback function is a good idea, I
think, but only for programs that know about it. It think that the
default behaviour should be as it currently is: if the python program
doesn't make any "funny" calls (like the misnamed
MacOS.EnableAppswitch, which disables all python's event processing)
it should work as it currently does. The issue is, however, tied to
the next one.

>    c) Standard I/O window.  I would like to make it possible that an
>       embedding app can completely disable to console window
>       (essentially all writes to the C level stdout/stderr would yield
>       write errors (or be ignored?) and all reads from stdin would
>       raise EOFError).  The app can them use some Python code that
>       substitutes something else for sys.stdout etc. so that it is
>       redirected to a window that it manages for itself.  This would
>       be useful for Tk, for instance (Tk dies when you click in the
>       SIOUX window, but it would be easy to connect the console to a
>       Tk text widget).

Definitely agreed. Here's an idea:
- Someone writes a console output window driver (in C). This is
  something that has an interface similar to the SIOUX low-level
  interface (writecharstoconsole(), readcharsfromconsole(), etc) but
  does not ever ever ever look at the event queue itself. CW7 SIOUX
  was advertised as doing this, but messed some things up (cut/paste
  handling). Also, the names should, unfortunately, be different so we
  can't use sioux. Finally, since the driver should never ever read an
  event the should be a callback (to call from readcharsfromconsole())
  which is called until enough events have been passed to
  handleoneevent() to satisfy the outstanding request.
- We create a builtin module that allows access to the functionality
  of the above.
- We write routines writecharstoconsole(), etc. that will call the
  appropriate python methods of a 'sioux object'. The initial sioux
  object will, of course, be the thing created previously, so when you
  start a normal python interpreter everything behaves as it does now.

  However, there's also an interface that allows a python program (or
  a C program, if python is embedded in another application) to divert
  all sioux I/O to your own object. You could even implement your own
  object using a sioux object (or multiple sioux objects if the
  implementation in the first step allows it, which would be a big
  benefit for someone implementing a python IDE).

- We redo the event loop (which is used by default, and entered once
  every umpteen python machine instructions, or when we're waiting for
  user input) to allow modules (such as the sioux module, or
  framework, or stdwin) to subscribe to the event loop. When there's
  an event available everyone subscribed gets a chance to look at it,
  with the return specifying whether the event has been handled or
  not. The sioux module will subscribe (if it is active), and also two
  other modules, one that handles command-dot and one that handle "the
  outside world", clicks in the desktop, that sort of thing.

  There's one potential problem: the menu bar. One possibility would
  be to do a generalized menu interface, but a better (albeit slightly
  clumsier) one would be to have the event loop peek at the current
  top window and install the correct menu. This will have the
  advantage of working better when embedding python.

  Of course, you can still turn off the event loop and handle all
  events by yourself, possibly passing events to this code with
  MacOS.HandleEvent.

So what does all this buy us? The main thing is that, given a
scriptable external editor, a minimal IDE is now simple. Create a
Python program that sets up a few menus and starts the interpreter
inside a try/except clause. Upon an exception you point the editor at
the offending line with an appleevent. Similarly, if you get a "run
script" appleevent you open a window and run the script. Thinking of
the rest of the possibilities is left as an exercise to the reader:-)

> 5) Preferences.  Still not as smooth as could be.  I guess that the
>    run-time options that can currently only be set by hitting Option
>    while Python is being launched should also be taken care of by a
>    preferences panel.

Definitely, the defaults for the option-launch options should be
settable from EditPythonPrefs. Actually, I'm still undecided about the
EditPythonPrefs program. Initially the implementation of setting the
preference file was completely in C in the interpreter, but I felt
that that was a bit silly, so I removed it and created
EditPythonPrefs. What do people think: is a separate
preference-setting program a good idea or should the code move back
into the interpreter?
--
Jack Jansen             | ++++ stop the execution of Mumia Abu-Jamal ++++
Jack.Jansen@cwi.nl      | ++++ if you agree copy these lines to your sig ++++
http://www.cwi.nl/~jack | see http://www.xs4all.nl/~tank/spg-l/sigaction.htm 

=================
PYTHONMAC-SIG  - SIG on Python for the Apple Macintosh

send messages to: pythonmac-sig@python.org
administrivia to: pythonmac-sig-request@python.org
=================