Go to the previous, next section.

# Using ILU with Python

## Introduction

This document is for the Python programmer who wishes to use ILU. The following sections will show how ILU is mapped into Python constructs and how both Python clients and servers are generated and built.

## The ISL Mapping to Python

### Names

In general, ILU constructs Python symbols from ISL names by replacing hyphens with underscores. For example, an ISL object type `T-1` would correspond to the Python class `T_1`. Any place an ISL name appears as part or all of a Python identifier, this translation occurs.

### Interface

Each ISL `interface` `I` generates two Python modules: one named `I` containing common definitions, and another named `I__skel` containing skeletons (server stubs). For example, `INTERFACE map-test;` generates the Python modules `map_test` and `map_test__skel`, contained in the files ``map_test.py'` and ``map_test__skel.py'`, respectively.

### Basic Types

The basic ISL types have the following mapping to Python types:

1. BYTE, BOOLEAN, SHORT CHARACTER, CHARACTER, SHORT INTEGER, INTEGER, and SHORT CARDINAL all map to Python int.
2. LONG INTEGER, CARDINAL, and LONG CARDINAL all map to Python long int.
3. SHORT REAL and REAL map to Python float.
4. LONG REAL maps to the Python type ilu_longreal, a type implemented by the ILU Python runtime. This type has limited functionality, but can be passed around without loss of precision, converted to float or int, and compared. A value of this type may be constructed by calling `ilu.LongReal()`.

#### Constant

ISL constants translate to Python variables initialized to the specified value. For example,

    CONSTANT pi : real = 3.14159265358979323846;

maps to

    pi = 3.14159265358979323846e0

### Strings

An ISL `SEQUENCE OF SHORT CHARACTER` maps into a Python string. `SEQUENCE OF BYTE` is also mapped into a Python string.

### Pickles and Typecodes

A value corresponding to the ISL type `PICKLE` is an instance of the Python class `ilu.Pickle`. Instances of this class have the following methods:

- `typecode()` - returns the typecode of the pickle's value as a string.
- `value()` - returns the Python form of the value in the pickle.
- `bytes()` - the pickled bytes of the pickled value as a string.

The constructor for this class takes two arguments, typecode and value, and returns a new pickle containing the value specified by value of the ISL type specified by typecode. Pickles may also be created by calling the constructor with a single argument string, which must be the result of an earlier call on the `bytes()` method of another pickle instance.

Typecodes are represented by the Python class `ilu.Typecode`. Typecodes are constructed with a single string argument, of the form `'interface.type'`, where interface is the ISL name for the interface, and type is the ISL name for the type. Instances of the `Typecode` class support the method

- `id()` - return the ILU type ID (CORBA repository ID) for the typecode's type.
- `name()` - return the ISL name of the typecode's type.

Note that typecodes for the built-in ILU types (`boolean`, `cardinal`, etc.) are available through this mechanism as well as typecodes for constructed types. For example, the Python call `ilu.Typecode("ilu.cardinal")` will return the typecode for the ILU `cardinal` type.

### Constructed Types

#### Enumeration

Enumerations are mapped to a method-less class object which contains an attribute of the correct type and value for each value in the enumeration. The class also contains a dictionary, called "__image__", for each enumeration type that maps an enumeration value to a string corresponding to its Python enumeration value name.

For example,

    TYPE color = ENUMERATION red, dark-blue END;

maps to

    class color:
        red = 0;
        dark_blue = 1;
        __image__ = {
           red: 'red',
           dark_blue: 'dark_blue'};

#### Array

An ISL array maps into a Python list with the specified number of elements. Tuples as well as lists are accepted as input, but lists are always produced as output from ILU. Arrays of BYTE or SHORT CHARACTER are represented with Python strings.

#### Sequence

Sequences of BYTE or SHORT CHARACTER are represented as Python strings.

If your ILU system has been configured with --enable-python-dictionaries, sequence types matching a particular profile will be mapped to Python dictionaries. The sequence type must have a name that ends with either "dict" or "Dict"; the base type of the sequence type must be a record type; the record type must have exactly two fields; the two fields must be named `name` and `value`, in that order; and the type of the `name` field must be either an integer, byte, string, or cardinal type.

All other ISL sequence types map into Python lists. Tuples as well as lists are accepted as input, but lists are always produced as output from ILU.

#### Record

ISL records map into generated Python classes with the same name, with the record's field names as attributes. The name of the record becomes a constructor function which accepts exactly the same number of arguments as the record has fields, in the same order.

For example, a record value of the ISL type

    TYPE segment = RECORD left-limit : integer, right-limit : integer END;

with a left-limit of -3 and a right-limit of 7 would map to

    segment(-3, 7) => <segment:{'left-limit' : -3, 'right-limit' : 7}>

#### Union

An ISL union maps into a Python tuple with two components: an integer discriminator, and the discriminated value. There are three possibilities:

1. If the discriminator matches one of the union case values of an arm, the second component is of the type specified by that arm.
2. If the discriminator matches no union case values and there is a default arm, the second component is of the type specified by the default arm.
3. If the discriminator matches no union case values and there is no default arm but the union has the `OTHERS` attribute, the second component is `None`.

#### Optional

A value corresponding to the ISL type `OPTIONAL T` may be `None` (indicating the null case) in addition to the values of the type T.

### Object Types

Each ISL object type is mapped into a Python class. These classes have the methods specified in the ISL, as well as some built-ins.

#### Surrogate and True Object Types

All surrogate object types inherit from `iluRt.IluObjSurr`, which in turn inherits from `iluRt.IluObject`. True object types inherit from `IluRt.IluObjTrue`, which also inherits from `iluRt.IluObject`. The method `IluTrueP()` will return a true value on true instances, and a false value on surrogate instances. The string binding handle of an object instance can be retrieved with the method `IluSBH()`. The object-id of an instance can be retrieved with `IluObjectID()`; it returns a tuple containing a string server ID and a string instance-handle. If support for the CORBA `IIOP` is configured into your ILU build, the string IOR of an instance can be retrieved by calling the function `ilu.IOROfObject()`, passing the instance as the argument. The type name of the most specific type of an instance can be retrieved with the method `IluTypeName()`; the unique ID of that type can be retrieve with the method `IluTypeID()`.

Object types which inherit from the ISL type `ilu.CORBA-Object` (which include all object types defined with OMG IDL), will inherit from the Python class ``ilu.CORBA_Object``, which is the same as the class ``CORBA.Object``.

#### Methods, Parameters, and Exceptions

ISL methods of an object type map to Python methods of the corresponding class. `IN` and `INOUT` parameters appear in the Python method signature in the same order as they do in ISL.

Let us define a result value to be either a return value (corresponding to a method's return type) or an `INOUT` or `OUT` parameter. Result values are returned by the Python method as a tuple, with the return value (if present) appearing before any parameters. If the method has only one result value, then it is simply returned (i.e., a tuple of length one is not constructed to hold this value). If the method has no result values, then `None` is returned.

An ISL exception translates to a Python variable initialized with a string representing the exception. These variables are used in Python `raise` statements in object implementation code, and in `try ... except` statements in client code. For example, the declaration

    EXCEPTION division-by-zero;

in the interface `map-test` maps to the following statement in ``map_test.py'`:

    division = 'map-test: division-by-zero'

`ASYNCHRONOUS` methods have no return values and raise no user-specified exceptions. They may return before the completion of the true method. `FUNCTIONAL` methods that have no parameters are cached so that a surrogate address space makes only one call to the true address space to retrieve the return value.

#### Garbage Collection and COLLECTIBLE

All instances of ILU object types are covered by the normal Python garbage collection; i.e., the application program must maintain a reference to the instance, or it will be garbage collected. With true instances of COLLECTIBLE object types, the ILU kernel will maintain an additional reference to the instance as long as it has registered clients using that instance.

## Access to standard ILU features

### Servers and Ports

Each object exported by an implementation must belong to a true server, an instance of the Python type `ilu_Server` which is implemented by the ILU runtime. An `ilu_Server` can be created by calling the function `ilu.Server(serverID, port-info, objectTable, default?)` which returns a value of type `ilu_Server`. If serverID is a string, it specifies the server ID; if it is `None`, one will be invented automatically. The port-info is either `None`, in which case no `ilu_Port` will be created for the server, or a sequence of either two or three values. The first value is always a string naming the protocol to use on the port, or may be `None` to indicate the default protocol. The second value is either a tuple of strings indicating the transport elements to use, or `None` to indicate the default transport stack. The third value, if provided, is a boolean value; if 'true', indicates that the port should be private, which means that it won't be advertised in the SBH of an object exported through this server. The objectTable argument is an object table for use with the server. The default? argument, a boolean value, says whether or not to make this server the default server. Additional ports can be added to a server with the ``addPort()`` method, if an application needs to make it available with via multiple protocols or addresses.

See the description of `ilu.Server` in the API reference for details of the methods available on an `ilu_Server` instance.

An older version of `ilu.Server`, called `ilu.CreateServer` is still available. See the API reference for details.

The default server is used for an exported object if a server is not otherwise specified. If an object is exported before any servers have been created, one will be created automatically using default parameters and a message to that effect will be written to stderr.

#### Object Tables

The objectTable argument to `ilu.Server` and `ilu.CreateServer` allows specification of a callback function for creating true instances on demand. The callback function should take one argument, a string, which is the instance handle of the instance to be created, and return a true instance.

On the client side, surrogate instances may be created by calling `ilu.FindOrCreateSurrogate`. The first call on this surrogate instance which attempts to communicate with the server will cause the object table to be invoked, and the true instance of the object to be created.

#### Server Relocation

It is sometimes useful to have a `dummy' server, that will redirect any requests to it to a real server somewhere else. This can be used for load balancing, automatic start-up of services, redirecting name service, code migration, and other various purposes. ILU supports this via a mechanism called server relocation, which can be used in Python via the ``setRelocator`` method on the ``ilu_Server`` class.

### Threading and Event Loops

To use threads, you must have configured both ILU and Python with thread support when building them. If you have done this, your ILU/Python runtime support will be thread-capable. To have ILU begin using threads, place a call to the function `ilu.ThreadedOperation()` in your Python program before any other ILU calls are made.

#### Animating Servers

Running the ILU main loop by calling `ilu.RunMainLoop()` brings the true servers to life. This function does not return until `ilu.ExitMainLoop()` is called. If you are using ILU with `Tkinter`, you should import `ilu_tk` before creating a loop handle, or calling `RunMainLoop`. `ilu_tk` sets things up so that both Tk and ILU events are handled.

#### Using Alarms

In order to schedule a Python function to be called at a certain time in the future when executing the ILU main loop, an `ilu_Alarm` may be used. Objects of this type are created by calling `ilu.CreateAlarm()`. An `ilu_Alarm` must be set to have any effect.

The alarm's method `set(time, proc, args)` is used to set the alarm. The `int`, `float`, or `ilu_FineTime` `time` argument is the time at which the alarm will fire; the `proc` argument is the Python function that will be called when the alarm fires; and the `args` argument is a tuple of arguments to be passed to `proc`. The tuple `args` must match `proc`'s signature. For example, if `proc` is declared `def P(a, b):` then `args` must be a two-tuple. Likewise, if `proc` takes only one argument then `args` must be a one-tuple, or if no arguments then a zero-tuple.

The function `ilu.FineTime_Now()` may be called to obtain ILU's idea of the current time. A value `sec` of type `int` or `float` in units of seconds may be converted to type `ilu_FineTime` by calling `ilu.FineTime(sec)`. Values of type `ilu_FineTime` may be compared, added, and subtracted. These operations may be used to construct values representing any relative time (subject to precision and range limitations), which is what is needed by an alarm's `set` method.

The alarm may be set multiple times with different arguments, in which case the parameters of the most recent call to `set` are in effect. Thus, once an alarm fires, it may be reused by calling `set` again.

An alarm may be unset by calling its method `unset()`.

### Custom Records

ILU generally supports a facility named custom records. This means that an application can declare that the language-specific mapping of a particular record type ISL(A) to lang(A) is to be overridden, and that instead a specific type X will be used in this language to represent values of ISL(A). In Python, this is done by simply replacing the generated class definition with a different class definition.

For example, suppose we had the ISL record type

    INTERFACE Ifc;
      ...
    TYPE Foo = RECORD color : RGB-tuple, position : XY-pair END;

The normal mapping of `Ifc.Foo` to Python would be to a class called `Foo` with the following definition:

    class Foo (iluRt.IluRecord):
        __ilu_type_name__ = 'Ifc.Foo'
        def __init__(self, _color, _position)
            self.color = _color;
            self.position = _position;

        def __getinitargs__(self):
          return (self.color, self.position)

To override this, define a new class in your application that has matching signatures for `__init__` and `__getinitargs__`, and a matching value for `__ilu_type_name__`. It must also inherit from `IluRt.IluRecord`. Then assign the class object for this new class to the symbol `Foo` in the Python module `Ifc`. So:

    class MyFoo (iluRt.IluRecord):
        __ilu_type_name__ = 'Ifc.Foo'
        def __init__(self, _color, _position):
            self.color = _color
            self.position = _position
            self.some_other_attr = whatever_I_want
            call_some_other_code(self)

        def __getinitargs__(self):
            return self.color, self.position

        ...possible other methods...

    Ifc.Foo = MyFoo

### String Binding Handle Formation

To use object tables properly, it is usually necessary for a client program to create a surrogate instance for which the true instance does not yet exist. In Python, this is done by creating a string binding handle for the object, then calling ``ilu.ObjectOfSBH()`` on that SBH. String binding handles may be formed by calling the function ``ilu.FormSBH()``.

### Simple Binding

A true instance may be published with the simple binding service by calling its method `IluPublish()`. A true instance may be unpublished by calling its method `IluWithdraw()`.

A published ILU object may be obtained by calling `ilu.LookupObject(sid, ih, cl)`, where `sid` is object's server's server ID, `ih` is the object's instance handle, and `cl` is its class.

### Principal Identities and Passports

An ILU passport (see section Security) is represented in Python by an instance of the ``ilu_Passport`` object type. Instances of this type can be obtained by calling ``ilu.CreatePassport()``. Please see the documentation of that function for more information on the abilities of this object type.

The passport of the caller may be obtained in the true method by calling the ILU runtime routine `ilu.CallerIdentity()`. The `native' passport may be obtained by calling ``ilu.GetPassport()``. In the case of a local call, these two passports may be the same object. Passports are thread-local; that is, an application may use a different passport in each thread.

## Building Python/ILU Applications

### Stub Generation

To generate Python stubs from an ISL file, use the program `python-stubber`. Two files are generated from each ISL `INTERFACE name`:

- ``name.py'` containing code for constants, exceptions, and types defined in the interface, and
- ``name__skel.py'` containing code for the skeletons (server stubs) for object types defined in the interface.

Alternatively, for surrogate-side use the stubber can be run automatically by a hook in the `ilu` module. Calling ``ilu.AutoImport()`` will establish the stubber as part of the normal Python `import` machinery, and will cause ``.isl'` and ``.idl'` files in directories on your `ILUPATH` environment variable path to be automatically stubbed and loaded.

#### Command-line Options

The program `python-stubber` supports the following options:

- `-I directory` -- add directory to the list of directories to search for interface definition files. Note that the directory must be separated from the `-I` with whitespace, unlike the convention for C compilers.
- `-dir directory` -- put output files in directory. Will attempt to create directory with `"mkdir directory"` if not already present.
- `-quiet` -- run without normal output to stderr.
- `-stub` -- generate the ``name.py'` file.
- `-skel` -- generate the ``name__skel.py'` file.
- `-removefirst` -- for generated files, remove file before generating a new version of the file.

If neither `-stub` nor `-skel` is specified, both files are produced. However, if either is explicitly specified, only those specified will be produced.

### Implementing an ILU module in Python

A Python module that implements ILU objects of types defined in `INTERFACE I` also imports from `I__skel`. This gives access to the skeleton classes from which implementation classes inherit.

#### Implementation Inheritance

An implementation of object type T from interface I needs to inherit from the class `I__skel.T`. If there is inheritance in the ISL, and an implementation of a subtype wants to inherit from an implementation of a supertype, the skeleton class must be appear in the list of base types before the implementation class.

For example, objects for the ISL

    INTERFACE j;

    TYPE c1 = OBJECT METHODS one() END;
    TYPE c2 = OBJECT METHODS two() END;
    TYPE c3 = OBJECT SUPERTYPES c1, c2 END METHODS three() END;

could be implemented in Python by

    import ilu, j, j__skel

    class c1(j__skel.c1):
        def one(self):
            ...

    class c2(j__skel.c2):
        def two(self):
            ...

    class c3(j__skel.c3, c1, c2):
        def three(self):
            ...

In this case `c3`'s method `one` is implemented by `c1.one` and `c3`'s method `two` is implemented by `c2.two`.

#### Exporting Objects

An object can be exported in one of three ways:

1. The object's string binding handle may be obtained by calling its method `IluSBH()` and communicating this somehow to a client, who then turns the handle back into an object by calling `ilu.ObjectOfSBH(cl, sbh)`.
2. The object may be published using the simple binding service by calling its method `IluPublish()`. In order for this to be effective, the object must have a well-known object ID, or the object ID must be communicated to clients, so clients can know what to pass to `ilu.LookupObject`. The object ID is a function of the object's instance handle and its server's server ID.
3. The object may be returned by a method or passed back in a method's `INOUT` or `OUT` parameter.

An object's instance handle can be controlled by setting the instance variable `IluInstHandle` before the object is first exported. If this instance variable is not set, and instance handle will be invented automatically.

An object's server can be controlled by setting the instance or class variable `IluServer` to a value of type `ilu_Server`. The value of this variable at the time an object is first exported will be used as the server for that object. If such a variable is not set, the default server is used.

### Using an ILU module in Python

The ILU runtime interface is in the Python module `ilu`. Python definitions for ISL `INTERFACE I` are in the Python module `I`. As with any other modules in Python, these modules are imported using the `import` statement.

A client program may create an ILU object in one of three ways:

1. Knowing the string binding handle `sbh` and class `cl` of an object, call `ilu.ObjectOfSBH(cl, sbh)` which returns an instance of that class. For example, to obtain an instance of ISL type `square` from `INTERFACE shapes` whose string binding handle is `sbh`, one would call `ilu.ObjectOfSBH(shapes.square, sbh)`.
2. Knowing the object ID `(sid, ih)` and class `cl` of an object that has been published using the simple binding service, call `ilu.LookupObject(sid, ih, cl)` which returns an instance of that class (or `None` if the lookup fails).
3. Receive an instance as a result value from a method call that returns an object type or has an object type as an `INOUT` or `OUT` parameter.

### CORBA Support in Python

This release of ILU has several nods to an eventual CORBA mapping for the Python language. The Python `CORBA` module contains support for the classes ``CORBA::ORB`` and ``CORBA::Object``, and the ``CORBA::ORB_init()`` function. See the Python/ILU API Reference for more information on these.

### Freezing a Python Application Containing ILU

    From: "Martin v. Loewis" <loewis@informatik.hu-berlin.de>
    Subject: Freezing ILU
    Date: Fri, 13 Mar 1998 07:54:30 PST

    I currently try to freeze a Python application that uses ILU. With ILU
    building libilupython, this is already simple. It would be even
    simpler if ILU installed a file Setup in the library directory with
    the contents

      iluPr -L/usr/ilu-2.0a12/lib -lilupython -lilu

    (Of course, it could contain comments :-) This tells makesetup that
    the iluPr module is available by linking ilupython and python to the
    freezed image. With this installation, I can freeze my application
    with the command line

      PYTHONPATH=/usr/ilu-2.0a12/lib python -O freeze/freeze.py
            -o outdir -e /usr/ilu-2.0a12/lib myscript.py

    Of course, /usr/ilu-2.0a12 has to be replaced with the actual
    ILUHOME/lib in both cases. For the Setup file, needs to be done prior
    to the installation.

    Regards,
    Martin

The file ``ILUHOME/lib/Setup'` exists in this distribution, so it should be possible to `freeze' a Python image containing ILU with the commands

    % python -O freeze/freeze.py -o outdir -e ${ILUHOME}/lib myscript.py

assuming that ``myscript.py'` contains your Python program, and that ``ILUHOME/lib'` is on your `PYTHONPATH` environment variable.

### Python/ILU Environment Variables

A number of environment variables are consulted by the ILU Python support. The environment variables `ILUPATH` and `ILUPATH_NO_ILUHOME` are significant to the Python stubber. They collectively define a set of directories to be appended to the interface search path given on the relevant tool's command line. If `ILUPATH` is not defined, ``.'` and ``ILUHOME/interfaces'` are appended. If `ILUPATH` is defined, it should contain a colon-separated list of directories. That list will then be used, with an appended -- unless `ILUPATH_NO_ILUHOME` is defined (with any value) -- by ``ILUHOME/interfaces'`.

The Python language runtime supports the standard CORBA method `CORBA::ORB::list_initial_services()`. If the environment variable `ILU_COS_NAMING_IOR` is set to the IOR of a CosNaming service, ILU will offer the `NameService` service, using that IOR to access the service.

During execution, ILU can experience three kinds of internal error conditions: assertion failures, memory allocation failures, and `check' failures (similar to an assertion failure). What it does when any of these three are experienced can be set, in the Python runtime, by setting the environment variables `ILU_ASSERTION_FAILURE_ACTION`, `ILU_MEMORY_FAILURE_ACTION`, and `ILU_CHECK_FAILURE_ACTION` to an integer value, which is then used to set the respective ILU kernel failure mode. See ``ILUSRC/runtime/kernel/iluxport.h'` for the documentation of which integer codes are appropriate for `ilu_SetAssertionFailureAction()`, `ilu_SetMemFailureAction()`, and `ilu_SetCheckFailureAction()`.

Also during execution, the Python import mechanism is augmented by default with an additional module loader which will load support for ILU ISL or OMG IDL interfaces found on the `ILUPATH` environment variable directly into Python. Automatic enabling of this mechanism can be defeated by setting the environment variable `ILU_PYTHON_DISABLE_AUTOIMPORT` to any value before loading the ILU module into Python. In addition, setting the variable `ILU_PYTHON_IMPORT_VERBOSE` will cause the auto-import mechanism to print status messages when loading an interface.

## Python/ILU API Reference

### Identifiers Exported From Module `ilu`

Function: AutoImport ([path=() [verbose=0]])

If called, enables the auto-loading of ``.isl'` and, if OMG IDL support is configured into ILU, ``.idl'`, files that are on the user's `ILUPATH` environment variable. The `python-stubber` program is run to generate the Python surrogate stubs for the interface description into a temporary directory, and those stubs are loaded into the current program. The stubber is re-run every time the interface is imported. If an error occurs while producing the Python stubs, an exception is raised and the import process stops. The path parameter has no effect; the verbose parameter will cause various messages to be written to the standard output during the process of importing, if set to a non-false value.

Function: CallerIdentity ()

Returns the passport containing identities of the caller. This routine is only valid inside the code of a true method.

Constant: CORBAMapping

A value which evaluates to Python boolean True if the CORBA mapping for Python has been selected, and False if the `classic' ILU mapping has been selected.

Function: CreateAlarm ()

Creates an object of type `ilu_Alarm`.

Function: CreateLoopHandle ()

Creates and returns an instance of a "loop handle" object, which can be passed to `ilu.RunMainLoop` and `ilu.ExitMainLoop()`.

Function: CreatePassport ()

Creates and returns an empty instance of a ``ilu_Passport`` object. The ``ilu_Passport`` object is used to provide a sense of identity in the ILU system. It can hold any number of different identities, each of which is represented with an appropriate data structure that varies from identity type to identity type.

The ``ilu_Passport`` object type has the following methods:

- ``lookupIdentity (IDENTITY-TYPE-NAME)`` - returns the data structure for the specified identity, if the passport contains one; Returns `None` otherwise. Raises `ilu.IluGeneralError` if the named identity type does not exist. The identity type ``'ConnectionIdentity'`` is always supported; the identity type ``'SunRPCAuthUnixIdentity'`` will be supported if support for the `sunrpc` protocol has been configured into ILU.
- ``addSunRPCAuthUnix (HOSTNAME, UID, GID, TUPLE-OF-GROUPS)`` - adds an identity of type ``'SunRPCAuthUnixIdentity'`` to the passport with the specified HOSTNAME, UID, GID, and TUPLE-OF-GROUPS. See Appendix A of RFC 1831 at `http://info.internet.isi.edu:80/in-notes/rfc/files/rfc1831.txt` for details on the meaning of these parameters. This method will only be available if support for the `sunrpc` protocol has been configured into ILU.

Function: CreatePipeline ()

Creates and returns an empty instance of a ``ilu_Pipeline`` object. The ``ilu_Pipeline`` object is used to allow multiple requests to be outstanding on non-concurrent protocol streams. The ``ilu_Pipeline`` object has no methods.

Function: CreateServer ( [serverID [transport [protocol [objtable]]]] )

This function is obsolete; you should use `ilu.Server` instead.

Used to create an `ilu_Server` object with the specified serverID, transport, and protocol. If serverID is unspecified or `None`, an identifier will be invented automatically. If transport or protocol are unspecified or `None`, they will default to `('sunrpcrm', 'tcp_0_0')` and `'sunrpc'`, respectively. (Other combinations that would work are transport of `('tcp_0_0')` and protocol of `'iiop_1_0_1'`, transport of `('sunrpcrm', 'tcp_0_0')` and protocol of `'courier'`, and transport of `('tcp_0_0')` and protocol of `'http'`, depending on the configuration of your ILU system.) The first time ``CreateServer`` is called, the server so created becomes the default server. If there is no default server when one is required, one will be created using default parameters and a message will be issued on stderr. The objtable argument allows specification of a callback function for creating true instances on demand. The callback function should take one argument, a string, which is the instance handle of the instance to be created, and return a true instance.

See the description of `ilu.Server` for a description of the methods available on the `ilu_Server` object.

Function: DefaultServer ()

Returns the default server.

Constant: DictionaryPassing

A value which evaluates to Python boolean True if the configuration option --enable-python-dictionaries has been selected, and False otherwise. That is, this is True if certain sequence types are mapped to Python dictionaries.

Function: DoSoon (FUNCTION, ARGS-TUPLE, STRING-DESCRIPTION)

Causes the function FUNCTION to be run with args ARGS-TUPLE to be run at some point in the future, when the system finds it to be convenient. In the threaded world, a new thread is forked to run the function; in the non-threaded world, the function is executed at some point by the event loop as a background task.

Function: ExitMainLoop (loophandle)

Exits the ILU main loop, assuming it is running. The loophandle is created by a call to `ilu.CreateLoopHandle()`, and must have been previously used as an argument to a call to `ilu.RunMainLoop()`.

Constant: FALSE

A value which evaluates to Python boolean False.

Function: FindOrCreateSurrogate (server, instance_handle, class)

Creates a new surrogate instance of class class with `ilu.Server` server, and instance handle instance_handle. This is often used in clients in conjunction with an object table on the server.

Function: FineTime (seconds)

Converts its `int` or `float` argument seconds in units of seconds to type `ilu_FineTime`. Objects of this type can be compared, added, subtracted, and converted to `int` or `float`. The main use of objects of this type is in setting alarms.

Function: FormSBH (sid, ih, type, pinfo, tinfo_vec)

Forms a valid ILU string binding handle from the arguments and returns it. The sid and ih arguments are strings containing the server ID and instance handle for the desired instance. The type argument should be the Python class for the most specific object type of the desired object. The pinfo argument is a tuple containing the protocol information describing the object implementation's preferred communication protocol. The tinfo_vec argument is a tuple of tuples, specifying the transport stack needed to connect to the implementation. Each sub-tuple in the tinfo_vec is a tuple describing a particular transport layer.

For instance, to create a string binding handle for an instance of type `Foo.Bar`, with server id `"some-server-id"` and instance handle `"some-instance-handle"`, exported via `Sun RPC`, version 2, with program number 1000007, version 3, via `TCP/IP` from host `"foobar.somewhere.com"`, port 3456, we'd say
`sbh = ilu.FormSBH('some-server-id', 'some-instance-handle', Foo.Bar,
('sunrpc_2', 1000007, 3), (('sunrpcrm',), ('tcp', 'foobar.somewhere.com', 3456)))`
Note the comma used after `'sunrpcrm'` to create a true tuple; note also that use of this procedure requires some specialized knowledge, such as knowing that use of `Sun RPC` also requires use of the `Sun RPC` record-marking transport layer when used over `TCP/IP`.

Constant: FineTimeRate

The precision of type `ilu_FineTime` in seconds is the reciprocal of this constant.

Function: FineTime_Now ()

Returns the current time as an `ilu_FineTime` object.

Function: FormSBH (objectID, contactInfo)

Returns the string binding handle corresponding to the object id objectID and contact info contactInfo. This is the inverse of ``ParseSBH``.

Function: GetFDBudget ()

Returns the current setting of the file descriptor budget.

Function: GetPassport ()

Returns the current passport for this thread. See also ``CreatePassport()`` and ``SetPassport()``.

Function: GetPipeline ()

Returns the current pipeline context for this thread. See also ``CreatePipeline()`` and ``SetPipeline()``.

Function: GetSerializer ()

Returns the current serialization context for this thread. See also the ``createSerializer()`` method on the ``ilu_Server`` class, and the ``SetSerializer()`` function.

Exception: IluGeneralError

An exception that may be returned from the ILU runtime. This exception is used to return all `standard' exceptions, with a string value to indicate the specific type of standard exception that occurred.

Exception: IluProtocolError

An exception that may be returned from the ILU runtime. This exception is raised for all on-the-wire exceptions, with a value that indicates which kind of protocol exception occurred.

Exception: IluUnimplementedMethodError

An exception that may be returned from the ILU runtime. Raised when an unimplemented method is called, typically on a true instance.

Exception: IluUnknownTypeIDError

An exception that may be raised from the ILU runtime. It indicates that the associated type ID value is unknown in this address space.

Function: IOROfObject (obj)

If the `IIOP` protocol has been configured in, returns the string IOR of the object, as specified in the CORBA 2 IIOP specification. If the `IIOP` protocol has not been configured in, throws an error.

Function: LongReal (v)

Converts its `int`, `float`, or sixteen-integer `list` or `tuple` argument to type `ilu_LongReal`. In case of a list or tuple, the elements encode the bytes of the IEEE long real value, from most significant to least.

Function: LookupObject (sid, ih, cl)

Returns the object with object server ID sid, object instance handle ih, and Python class `cl`, assuming it was previously published using the simple binding service. If the lookup fails, `None` is returned.

Function: ObjectOfSBH (cl, sbh)

Returns the object corresponding to the Python class cl and string binding handle sbh.

Function: ParseSBH (sbh)

Returns the pair (object id, contact info) corresponding to the string binding handle sbh.

Function: RegisterCustomSurrogate (class)

Registers class as the object type to create when receiving a surrogate of the type indicated by the `_IluClass` field of class. class must be a subtype of the default surrogate type for this ILU type. This allows custom surrogates, with implications for caching and other object-type-specific functions.

Function: RegisterInputHandler (file, handler_fn)

Sets up an association between the file (which must be a file object opened for reading), and the handler_fn (which must be a callable function with no arguments) so that handler_fn is called whenever input is available on file. This is useful for implementing a server that also responds to commands typed to its standard input, for example. Passing a value of `None` for the handler_fn removes the association. This procedure should only be used in non-threaded applications. In threaded applications, you should fork a thread to handle this, instead.

Function: RegisterOutputHandler (file, handler_fn)

Sets up an association between the file (which must be a file object opened for writing), and the handler_fn (which must be a callable function with no arguments) so that handler_fn is called whenever input is available on file. Passing a value of `None` for the handler_fn removes the association.

Function: RunMainLoop (loophandle)

Runs the ILU main loop. The argument loophandle is a "handle" on that loop invocation, created by a call to `ilu.CreateLoopHandle()`. This function can be used with either threaded or non-threaded use of ILU/Python. In the threaded use, it simply runs `sleep.sleep` in the calling thread.

Function: Server ( serverID cinfo objtable useAsDefault? )

Used to create an `ilu_Server` object with the specified serverID, transport, and protocol. If serverID is unspecified or `None`, an identifier will be invented automatically. If cinfo is `None`, only an `inmem` port will be created for the server. Otherwise, cinfo should be a tuple containing either two or three values, controlling the characteristics of the port created for the server. The first value is the protocol to use. If specified as `None`, the default protocol will be used. The second value is a tuple of strings specifying the transport stack. If specified as `None`, the default transport stack will be used. The optional third value is a boolean; if True, it specifies that the port created will be private, meaning that it will not be advertised in the cinfo of objects exported through this server. If omitted, it defaults to False. The objtable argument allows specification of a callback function for creating true instances on demand. The callback function should take one argument, a string, which is the instance handle of the instance to be created, and return a true instance. If useAsDefault? is True, the server will become the default server.

An `ilu_Server` object has the following methods:

- ``id ()`` - returns the string identifier of that server.
- ``addPort (TRANSPORT, PROTOCOL [, PRIVATE?])`` - adds a port with the specified TRANSPORT and PROTOCOL (described above) to the server instance. If PRIVATE? is specified as True, the port created will be private; otherwise, it will be public.
- ``createSerializer ()`` - creates and returns a new serialization context object.
- ``setRelocator (RELOCATOR-FUNCTION)`` - sets the relocation procedure of the server to be RELOCATOR-FUNCTION. RELOCATOR-FUNCTION should be a function with no arguments, that returns either `None`, or a tuple with two elements. If it returns the two-element tuple, the first element should be a string specifying pinfo as in the arguments to `CreateServer`, and the second argument should be a tuple of tinfo, again as in the arguments to `CreateServer`.
- ``nativeCInfo ([ PRIVATE? ])`` - returns a tuple containing the protocol and transport info for the first port of the server. If PRIVATE? is specified, the first private port will be used; otherwise the first public port will be used. If no cinfo is available for the server, `None` will be returned.
- ``addCInfo (PINFO, TINFO)`` - adds the specified PINFO and TINFO to the connection information for the port. This can be used to override the natural connection information for a server.

Function: SetCalloutExceptionHandler (handler-fn)

This function can be used to define a function handler-fn which is called when an internal Python exception is signalled in code called from the ILU C code. The handler function receives four arguments: a string indicating where in the ILU runtime the exception was encountered, the exception type, the exception value, and a traceback object. This function is typically used to note the exception to a file or stderr; see the example usage in ``ILUSRC/runtime/python/iluRt.py'`. If a parameter of `None` is passed to `SetCalloutExceptionHandler`, it cancels any handler function in use, and a default built-in one is used.

Function: SetDebugLevel (flags-or-switches)

Sets the ILU kernel debugging flags according to its `int` argument, if an int is specified, or via the colon-separated list of debug switches, if a string is specified. See the Debugging section of the ILU Manual for more information on these switches.

Function: SetFDBudget (desiredbudget)

Attempts to set the file descriptor budget. Returns what the new budget actually is (may be different than requested).

Function: SetMainLoop (DoEvent, RegisterInput, CancelInput, RegisterOutput, CancelOutput, CreateAlarm, SetAlarm, CancelAlarm)

The purpose of this function is to be able to use a foreign main loop (such as for a user interface toolkit) with an ILU server. The details will not be described here. Look at the runtime module ``ilu_tk`` for an example of its use. This function should only be used with non-threaded use of ILU/Python.

Function: SetPassport (passport)

Sets the current passport identity for this thread, and returns the passport active before this call. Either of these can be `None`. Also see the function ``CreatePassport``, and the function ``GetPassport``.

Function: SetPipeline (pipeline)

Sets the current pipelining context for this thread, and returns the context active before this call. Either of these can be `None`. Also see the function ``CreatePipeline``, and the function ``GetPipeline``.

Function: SetSerializer (serializer)

Sets the current serialization context for this thread, and returns the context active before this call. Either of these can be `None`. Also see the ``createSerializer`` method on the class ``ilu_Server``, and the function ``GetSerializer``.

Function: TCPDefaultBufferSize (size)

Sets the default buffer sized used for TCP/IP transport buffers to size. Returns the previous default buffer size. Raises ``IluGeneralError`` if support for the TCP/IP transport is not configured into ILU.

Function: TCPStatistics (*reset)

Returns a dictionary containing the current TCP/IP statistics for this process. If a True value is specified for the optional argument, the statistics counters are reset. If TCP/IP support is not configured into ILU, this routine will raise the exception ``IluGeneralError``.

Function: ThreadedOperation ()

Enables thread use in both the ILU kernel and the ILU/Python runtime. This routine should be called before any other ILU calls are made.

Constant: TRUE

A value which evaluates to Python boolean True.

Function: TypeID (cl)

Returns the ILU unique type identifier corresponding to the Python class cl.

Function: TypeName (cl)

Returns the ILU type name corresponding to the Python class cl.

Constant: Version

The ILU version string.

### Identifiers Exported from the `CORBA` Module

Variable: InitialReferences

A dictionary with string keys, and values of type ``CORBA.Object``. It is used to resolve strings passed as parameters to ``CORBA.ORB.resolve_initial_references()``. The following names are supported automatically by Python runtime:

- NameService
  If the environment variable `ILU_COS_NAMING_IOR` is bound to a string IOR for a OMG IDL `CosNaming::NamingContext` object instance, the Python runtime will attempt to create a surrogate for that instance locally, ping it, and if successful will bind it to the string `"NameService"`.

Exception: InvalidName

Raised when an invalid name is passed to ``CORBA.ORB.resolve_initial_references()``. Has the associated bad name as its value.

Class: Object (ilu.IluObjSurr)

A type which all object types defined in OMG IDL, or inheriting from `ilu.CORBA-Object` in ISL, participate in. It supports the following methods:

- `_is_a(type_uid)` - returns `True` if the object is of the specified type, `False` otherwise; raises `ilu.IluUnknownTypeIDError` if the type_uid is unknown in this address space;
- `_is_nil()` - returns `False`; raises `TypeError` if called via ``CORBA.Object._is_nil()`` on a non-Python-object type;
- `_non_existent()` - returns the logical inverse of the result of calling `ilu.PingObject()` on the object;
- `_is_equivalent(other)` - returns the result of comparing self and other with the Python `==` operator;
- `_duplicate()` - does nothing, returns self;
- `_release()` - does nothing, returns nothing;
- `_hash(max_value)` - returns `(hash(self) % (max_value + 1))`;
- `_get_implementation()` - raises ``IluUnimplementedMethodError``;
- `_get_interface()` - raises ``IluUnimplementedMethodError``;

The ``CORBA.Object`` class is actually implemented in ``iluRt.CORBA_Object``, so all classes which inherit from ``ilu.CORBA_Object`` will have access to these methods.

Class: ORB

The general class for manipulating the object request broker. There is typically only one instance of this class per address space. It is retrieved with the function ``CORBA.ORB_init()``; it supports the following methods:

- `object_to_string(instance)` - returns a string which can be used in a subsequent ``string_to_object()`` call;
- `string_to_object(string)` - if the specified string is well formed and specifies an object, the object is created locally and a reference is returned; the reference may be to a true instance if the string names a true instance; if the string is poorly formed, the Python exception ``ilu.IluGeneralError`` is raised. This method does not test for the existence of the instance.
- `resolve_initial_references(string)` - If the string argument is bound in the dictionary ``CORBA.InitialReferences``, the value is returned. Otherwise, the exception ``CORBA.InvalidName`` is raised. See the documentation of ``CORBA.InitialReferences`` for a listing of the names that are bound automatically, if any.

Function: ORB_init (argv=(), orb_id='ilu')

Returns an instance of ``CORBA.ORB`` with the specified orb_id (currently only the ORB ID `'ilu'` is supported). The arguments which may be passed in via argv are ignored.

### Methods and Attributes of ILU Objects

- `IluObjectID()` returns the object ID of the object.
- `IluPublish()` publishes the object using the simple binding service.
- `IluSBH()` returns the object's string binding handle.
- `IluTypeID()` returns the unique type identifier of the object's ILU type.
- `IluTypeName()` returns the type name of the object's ILU type.
- `IluWithdraw()` undoes the effect of IluPublish().

Special attributes of ILU true objects: One or more of the following attributes may be set in a true (implementation) object of an ISL object type to control certain aspects of that object.

- `IluInstHandle`, a string instance variable, gives the object's instance handle. If not present, an instance handle is invented automatically.
- `IluServer`, a variable of type `ilu_Server`, determines the object's server. This can be an instance or a class variable. If not present, the default server is used.

Go to the previous, next section.