pyobjc / pyobjc / Doc / TODO

=========
Todo list
=========

.. contents:

Introduction
------------

This document contains an (incomplete) list of work items. 

Important items
---------------

Better documentation
....................

There should be more developer documentation and end-user documentation is
virtually non-existant. Related to this is the website: This should be filled.

We should also add scripts to convert documentation to a format that is 
useable on the website.

Also needed: document listing the differences between Objective-C Cocoa and
Python Cocoa: which functions/methods are not available, list differences
in arguments (e.g. NSBeginAlertSheet has a variable number of arguments in
Objective-C, the format-arguments are not present in Python).

Multi-threading support
.......................

The code should be mostly thread-safe, but this should be checked. Furthermore
we should add code that enables using python in multiple threads:

* Give up the global interpreter lock (GIL) before calling into Objective-C

* Make sure the current thread-state is stored in thread-local storage (TLS)
  before calling into Objective-C 

* Fetch the thread-state from a TLS during callbacks from Objective-C and
  create one if it doesn't exist yet. The latter assumes 1 python interpreter
  per process.

* Acquire the GIL during callbacks from Objective-C (this includes python
  methods called from Objective-C)

* A number of functions use static buffers, all in pyobjc_support.m and
  related to depythonify_c_value. Fixing this is relatively straightforward:
  raise a python exception if the conversion fails, instead of returning an
  error-string.

NOTE: If we don't mind doing this only for Python 2.3 we can use the interface
defined by PEP 311

NOTE2: The autoGIL is quite usefull, but unless our code gets called from a
different thread, that does not yet have a Python thread context. This may 
happen when embedding a PyObjC solution in an existing Cocoa application.

NOTE3: This is not really an important item.

XXX (Ronald): I'll probably add PEP311 support after we do a release  with
Panther support. This would make it safer to use PyObjC embedded in an 
multithreaded application. Specifically: grab the GIL when going from ObjC
to python, and release it when going back again. This is a half-way solution.

Test suite
..........

The test suite needs to be enhanced.

* tests for all functions in ``Modules/*/*Mapping*.m``

* tests for all non-generated function wrappers

* tests where Python implementation of method with output arguments returns
  the wrong value (type, number of values)

The first two bullets require at least some GUI tests.



Less important items
--------------------

Refactor some parts of the bridge
.................................

From the top of my head:

* Should write a function for calculating the signature for a function/method
  object that is to be added to a class (check informal_protocols and methods
  in the superclass for signature and "class-methodness"). Use this when 
  defining python subclasses of ObjC classes (currently has this hardcoded) 
  and in the implementation of objc.classAddMethod (currently doesn't support
  raw functions).

  Interface:
    PyObject* PyObjCSelector_MakeDefaultSelector(
    	PyObject* class, PyObject* protocols, PyObject* callable);

    - protocols is optional, and should be a writable list if passed in.
    - callable could be any callable, it should be a method, function,
      selector or classmethod({method,function}).
    - Return NULL and set PyExc if no conversion was performed, the new
      selector otherwise.

  Use this method in class-builder.m and in the implementation of 
  classAddMethods.

* Restructure selector.m, this file is too long and complicated. We could
  do away with the difference between method implemented in Python and ObjC.

* Likewise for class-builder.m, this file is way to large.

* Use libffi to do away with class-builder.m:find_real_superclass. And check
  if we can use libffi to simplify code.

* See XXX in Lib/objc/_convenience.py. That code masks a real, but elusive,
  bug.


Support for GNUstep
...................

We currently don't support GNUstep. Modules/objc/objc_support.h contains 
some definitions that help in supporting GNUstep, we should use those where
applicable. 

Support beyond that requires someone that actually tries to perform the 
port to GNUstep (and after that maintains it). 

Naming convention / coding style
................................

Global symbols should be named with a prefix. We currently use several
prefixes and some symbols do not have a prefix at all. 

See the document `Coding style` for a proposal for a coding style and naming
convention. The code should be changed to conform to this document.

.. _`Coding style`: coding-style.txt

Add templates for various project-types
.......................................

We currently have a Project Builder template for a basic PyObjC application. We
should simular templates for other usefull projects and most importantly a 
document-based application. 

Other possibilies include:

* Standalone Service

* IBPalette

* PreferencePane

* Screen Saver

* Cocoa Bundle

In contrast to a template for a document-based application these last four 
require additional (Objective-C) code: There needs to be a mechanism to 
initialize a python interpreter and load the python code in the project when 
the plugin/bundle is loaded. Furthermore we need to make sure that exactly one 
interpreter is created, even when more than one Python based plugin/bundle is
loaded.

NOTE: All these are supported for 'pure python' projects, we just have to 
find a way to make it easier to maintain PB templates. The currently is too
much manual labor involved in updating them.

Complete Cocoa wrapping
.......................

We do not yet have a 100% coverage of the Cocoa API's. We also need code in
the testsuite that checks if the function wrappers are working as expected.

Someone needs to check if we correctly export all constants from Cocoa and if
the generation script finds all global functions. Simularly for the annotations
for input/output arguments.

We also don't support all "difficult" methods yet, implementing these is
not too hard but it is a lot of work.

NSDecimal (the C-type) is not yet supported.

Pickle support
..............

Objective-C objects don't support pickling. They do pickle without errors using
protocol version 2 (Python >= 2.3a2), but that doesn't include the state of
the Objective-C object only that of the proxy.

This is post-1.0 work, in general this is a hard problem because it may 
involve object cycles that cross the Python-ObjC boundary.

NOTE: 1.0b1+ contains a patch that disables pickling even for pickle protocol 2,
that's more usefull than writing incomplete objects to the pickle.

NSCoder support
...............

It might be usefull to add default implementations of ``encodeWithCoder:`` and
``initWithCoder:`` methods to Python subclasses of Objective-C classes that 
implement these.

See also `Pickle support`.

Known issues
............

It is impossible to support methods with a variable number of arguments in the
generic code (you have to reimplement allmost all of the logic of these 
methods in order to know how many and which types of arguments are expected).
Luckily there are not many varargs methods and most (if no all) of them can
be easily avoided.

XXX: The paragraph above should be moved to the documentation, it is not a 
todo item.

All existing varargs methods should be located and documented. Where possible
we should provide custom wrappers, otherwise we should document alternatives.

We should further investigate why the call to ``PyType_Ready(&PyTuple_Type)``
in module.m is necessary. See `bug #77730`__.

.. _: http://sourceforge.net/tracker/index.php?func=detail&aid=777308&group_id=14534&atid=114534


Cleanup Examples
................

The CurrentConvertor example should be removed, this should be the same as the
final step of the tutorial. It isn't at the moment because additional cruft in
the example.

* addressbook.py
  Cleanup, maybe transform this into a usefull utility (import/export from/to
  CSV springs to mind).

* autoreadme.py
  Add documentation

* dictionary.py
  Should be a unittest, and should be added to the (non-existing) manual

* pydict-to-objcdict.py
  Move to unittests

* subclassing-objective-c.py
  Move to documentation (unittest?)

* super-call.py
  Move to documentation  (unittest?)

Add examples that demonstrate:

- how to use a lot of Cocoa features

- how to integrate with MacPython


Access to method implementations
................................

Add a wrapper for 'instanceMethodForSelector:' and 'methodForSelector:', these
should return selector objects that call a specific C function. This would make
it possible to use classAddMethods to replace existing methods while still 
calling the previous implementation.

The same mechanism could be used to wrap "simple" global functions. OTOH the
current mechanism works good enough at the moment.

Performance tuning/testing
..........................

Design and implement a set of performance tests for the bridge. Use this to 
investigate and fix any possible performance problems.

Robustness
..........

Make core bridge more robust w.r.t. order of loading frameworks. You currently
get incorrect wrappers if you manually load the AppKit.framework and then 
import AppKit. I (Ronald) know how to do this, but this can wait until after 
1.0.

Add freelists
.............

PyObjCSelector objects and PyObjCObject objects are created on
a regular basis, we should check if using freelists would speed this up. See
also `Performance tuning/testing`.


Key-Value Encoding
..................

Implement the Key-Value encoding protocol for Py-ObjC hybrids, in a Pythonic
way. Do the same in OC_PythonObject (e.g. for pure-python objects used from
Objective-C)

Formal Protocols, Distributed Objects
.....................................

``DO`` seems to use formal protocols, we don't support those at all. 

Links to Apple documentation
............................

Links to Apple documentation are not stable, can we add a layer of indirection
here, e.g. link to the PyObjC website that will redirect to the right
location?

But: we should also provide links to locally installed documetation, especially
in the documentation that will be installed on the users machine.
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.