Title: Python and COM
1Python and COM
2Tutorial Agenda
- Introduction to COM
- PythonCOM Framework
- Using Python as a COM client
- Using Python as a COM server
- Advanced topics
- Futures
3Introduction to COM
4COM/OLE and ActiveX
- Component Object Model
- Specification for implementing and defining
objects - OLE is the old name, COM is the official name,
ActiveX is the marketing name - All the same - the Microsoft Marketing Machine
5What is a COM interface?
- A technique for implementing objects
- Uses a vtable to define methods
- Does not have properties
- Basically a C object with only public methods
- But not C specific - just borrowed
implementation technique - Allows implementation from other languages
- All interfaces have a unique ID
6IUnknown
- Base class of all interfaces
- Every COM object must implement
- Defines object lifetimes
- Reference counted using AddRef and Release
methods - Defines techniques for querying the object for
something useful - QueryInterface method
- No other functionality - simply defines these 3
methods
7Custom interfaces
- Any interface derived from IUnknown
- Therefore must follow IUnknown rules for
lifetimes - Derived?
- Means object can be used as its base. Simple
implementation using vtables - All interfaces are custom interfaces
- Not a standard part of COM per-se, just follow
its rules
8Objects vs. Interfaces
- Interfaces simply define functionality
- Objects, once instantiated, implement the
interface - Object class also has unique ID
- Objects always provide multiple interfaces
- At least IUnknown and some other functional
interface
9CLSIDs, GUIDs, UUIDs, IIDs
- COM defines 128 bit identifier, and API for
creating them - High degree of certainty that these are
globally unique - All use the same type and implementation, acronym
reflects different usage - IID Interface ID, GUID Globally Unique
Identifier, CLSID Class ID, UUID
Universally Unique Identifier, etc - API for converting to and from Strings
10Registering Objects
- Objects register themselves in the Windows
Registry - Register with their Unique CLSID
- Also register a name for the object
- COM provides API for translating, but names are
not guaranteed unique - Many objects self register
11Creating Objects
- Standard COM API for creation
- CoCreateInstance, passing
- CLSID identifying the object to create
- IID identifying the initial interface requested
12C Pseudo Code
- // Create an object, but only get back
- // IUnknown pointer, with new reference
- IUnknown pUnk CoCreateInstance(MyObject,
...) - // Ask the object for a pointer to a useful
implementation! - pUseful pUnk-gtQueryInterface( IID_IUseful, ...)
- pUnk-gtRelease() // finished with this.
- pUseful-gtDoSomethingUseful()
-
- pUseful-gtRelease() // Object now dies
13Custom Interface Example1 of 2
- Native Interfaces using Word
- You would be unlikely to use Word this way
- Demonstrative purposes only!
- gtgtgt import ni, win32com, pythoncomgtgtgt
opythoncom.CoCreateInstance \
("Word.Application", None, pythoncom.CLSCTX_ALL
, pythoncom.IID_IUnknown)gtgtgt oltPyIUnknown at
0x834b04 with obj at 0x423474gt
14Custom Interface Example2 of 2
- gtgtgt o.QueryInterface( \
pythoncom.IID_IPersist)ltPyIPersist at 0x85dd54
with obj at 0x423464gt - Almost identical to the pseudo code above
- In fact, Python is far better than C, as long
as we support the required interfaces natively - No AddRef or Release required, or even exposed
- Release() currently exposed, but not for long!
15IDispatch - poor mans COM1 of 2
- Also known as Automation
- Derived from IUnknown
- Defines vtable methods to determine dispatch
methods and properties at runtime - Perfect for scripting languages which have no
compile step, or which are not C! - Optionally uses Type Libraries so optimizations
can be made at compile time
16IDispatch - poor mans COM2 of 2
- What many people know as COM
- Microsoft marketing machine
- In reality, a small, but somewhat useful part of
COM - Many useful COM interfaces do not support
IDispatch - Native MAPI, Active Scripting/Debugging, ActiveX
Controls, Speech Recognition, etc - Very hard from C/C, very easy from VB
17Core InterfacesIntroduction
- COM tends to use interfaces for everything.
Example - Instead of using a file pointer/handle, a
Stream interface is used, which provides file
like semantics - Anyone free to implement the stream interface
using any technique they choose - Such interfaces not necessarily part of COM
per-se, but we consider them core interfaces
18Core InterfacesEnumerators
- Enumerators provide access into a list of values
- Provides Next, Skip, Reset and Clone methods
- Different enumerator interfaces for different
types - IEnumGUID - Enumerate list of GUIDs
- IEnumFooBar - Enumerate list of FooBars!
19Core InterfacesCollections
- Alternative technique for accessing lists
- Usually only used via IDispatch
- Uses tricks only IDispatch has available, such
as properties! - Therefore not a real interface
- Used to provide array like semantics for VB, etc
- Methods include Count() and Item(). Count often
implied by len(), Item() often omitted.
20Core InterfacesStreams and Storage
- IStream provides file like semantics
- IStorage provides file system like semantics
- Programs can write to this specification without
needing to know the destination of the data - COM provides implementations of these for
structured storage files
21Core InterfacesMonikers
- Provide file name to object mapping semantics
- Fundamental concept is to provide an indirection
level to an underlying object, and a program
neutral way of accessing the underlying object - File and URL Monikers do just that
- Pointer monikers allow anyone to implement an
abstract indirection to an object (e.g., into a
message store, etc)
22Core InterfacesConnectionPoints
- Provides simple callback functionality
- Client sets up connection point object
- Object passed to Connection Point Container
object - Container calls methods on the Connection Point
when appropriate - Typically used as an event mechanism (e.g.,
ActiveX Controls). This is how VB finds the list
of events for an object.
23Core InterfacesAnd the Rest
- Plenty of others not listed here
- Anything in core PythonCOM is considered core
- By us, anyway - YMMV -)
- Check out the sources, Help Files, or forthcoming
documentation - Who was going to write that?
- Extensions to PythonCOM - present and future
24Error Handling
- All methods use HRESULT return code
- Multiple success codes, and many failure codes
- ISupportErrorInfo interface for richer error
information - IDispatch uses EXCEP_INFO structure
- PythonCOM transparently maps these
- More detail in Server section
25PythonCOM Framework
26PythonCOM Framework
- Supports use of Python for both COM servers and
COM clients - Easy for the Python programmer
- Dispatch friendly with core support for most
common vtable interfaces - Easily extended for new vtable interfaces
27PythonCOM Extensions
- Model allows for COM extension DLLs
- Once loaded, looks like native support to the
Python programmer - MAPI, ActiveX Scripting and Debugging all use
this technique - Import them once, and PythonCOM will serve up
their interfaces - Makes for stable core, with more frequent
extension releases
28Using Python as a COM client
29Python COM ClientsThe Problem
- Calling a COM object from Python
- COM vtable C (not Python)
- IDispatch removes vtable requirement
- Imposes coding burden on client
- IDispatch is still vtable based, so core problem
remains
30Python COM ClientsThe Answer
- We need an intermediary between a Python object
and COMs vtables - These are called interfaces (c.f. gateways
for the server side - poor choice of terminology,
but this is what we use!)
31PythonCOM Interfaces1 of 3
- Very similar to standard Python extension modules
- Conceptually identical to wrapping any C object
in Python - 11 mapping between the COM pointer and Python
object - Pulls apart arguments using PyArg_ParseTuple
- Makes call on underlying pointer
- Handles errors, exceptions, and return values
32PythonCOM Interfaces2 of 3
PythonCOM
Interface
Server
Interface
Client
Interface
33PythonCOM Interfaces3 of 3
PythonCOM
Interface IDispatch
Client
Server
Wrapper
34IDispatch vs. vtable
- IDispatch implemented in PythonCOM.dll like any
other interface - No Dynamic logic implemented in DLL
- Only GetIDsOfNames and Invoke exposed
- win32com.client Python code implements all
IDispatch logic - Calls the above 2 methods dynamically to obtain
method and property information
35IDispatch Implementation
- 2 modes of IDispatch usage
- Dynamic, where no information about an object is
known at runtime - All determination of methods and properties made
at runtime - Static, where full information about an object is
known before hand - Information comes from a Type Library
- Not all objects have Type Libraries (including
Python objects!)
36Dynamic IDispatch Implementation1 of 5
- Implemented by win32com.client.dynamic
- Also makes use of win32com.client.build
- Uses __getattr__ and __setattr__ methods in
Python to implement its magic
37Dynamic IDispatch Implementation2 of 5
- Not perfect solution as
- __getattr__ has no idea if the attribute being
requested is a property reference or a method
reference - No idea if the result of a method call is
required (i.e., is it a sub or a function) - Python must guess at the variable types
- Big problem tends to be byref params - by
default these are not handled
38Dynamic IDispatch Implementation3 of 5
- win32com.client.Dispatch kicks it all off
- Demo
- gtgtgt import ni
- gtgtgt from win32com.client import Dispatch
- gtgtgt wDispatch(Word.Application)
- gtgtgt w.Visible 1
- Starts Winword, and makes it visible
39Dynamic Dispatch Implementation4 of 5
- Pros
- No setup steps - just works
- Provides quick scripting access to components
- Cons
- Relatively slow
- You need to know the object model of the target.
Not self documenting. - Actually, Python can make many objects self
documenting, but this is beyond the scope of this
40Dynamic Dispatch Implementation5 of 5
- Smart Dispatch vs. Dumb Dispatch
- To overcome some potential problems, Python
attempts to use Type Info even for dynamic
objects - Slows down considerably for certain objects
- win32com.client.DumbDispatch provides alternative
implementation which does not attempt to locate
type information - For many servers, will provide excellent results
and speed
41Static Dispatch Implementation1 of 4
- Generates .py file from Type Information
- win32com.client.makepy does this
- Python code then imports this module
- Python knows everything about the object
- No confusion between methods and properties
- Byref args handled correctly
- No dynamic lookups - much faster
42Static Dispatch Implementation2 of 4
- Demo
- C\gt cd \Program Files\Microsoft Office\Office
- C\gt \python\python \python\win32com\client\makepy
.py msword8.olb gt \python\msword8.py - ...
- Cgt start python
- gtgtgt import msword8 grind, grind -)
- gtgtgt w msword8.Application()
- gtgtgt w.Visible 1
43Static Dispatch Implementation3 of 4
- Pros
- ByRef args handled correctly
- Result becomes a tuple in that case
- All types handled correctly
- Python knows the type required, so doesnt have to
guess. More scope to coerce - Significantly faster
- Python source file documents methods and
properties available
44Static Dispatch Implementation4 of 4
- Cons
- Need to hunt down type library
- Need to enter cryptic command to generate code
- No standard place to put generated code
- Compiling code may take ages
- Not real problem, as this is a once only step
- Type library may not be available
- Many Cons listed are not permanent - help would
be appreciated!
45Dispatch, VARIANTs and Python Types
- VARIANT
- COM concept for IDispatch interface
- Just a C union, with a flag for the type, and an
API for manipulating and converting - IDispatch always uses VARIANT objects
- In reality, COM is not typeless - most servers
assume a particular type in the variant - Most (only!) complex code in PythonCOM deals with
VARIANT conversions
46Dispatch, VARIANTs and Python Types
- Python has 2 modes of conversion
- Python type drives VARIANT type
- Python knows no better
- Creates VARIANT based on type of Python object
- Known type drives VARIANT type
- For static IDispatch, Python often known exactly
type required - Attempt to coerce the Python object to VARIANT of
this type
47win32com.client Files1 of 2
- makepy.py, dynamic.py
- Static and dynamic IDispatch implementations
respectively - build.py
- Utility code used by both modules above
- CLSIDToClass.py
- Manages dictionary of Python classes, mapped by
CLSID. Code generated by makepy.py automatically
populates this.
48win32com.client Files2 of 2
- combrowse.py
- Basic COM browser that requires Pythonwin.
Simply double-click on it. - tlbrowse.py
- Basic Type Library browser that requires
Pythonwin - util.py
- Utiility helpers
- connect.py
- Connection point client base class
49Client Side Error Handling1 of 2
- Client interfaces raise pythoncom.com_error
exception - Exception consists of
- HRESULT
- 32 bit error code, defined by OLE
- Error Message
- Should be language independant
- (cont.)
50Client Side Error Handling2 of 2
- COM Exception Tuple
- Tuple of (wcode, AppName, AppMessage, HelpFile,
HelpContext, scode), all of which are application
defined - Exception object itself, or any part of it, may
be None - Arg Error
- Integer containing the argument number that
caused the error - Often None if error does not relate to specific
argument
51SWIG and COM Client Interfaces1 of 3
- Recent changes to SWIG allow it to generate
client side native interfaces - ie, any custom interface not based on IDispatch
can be generated - Uses existing SWIG functionality and M.O.
- ie, maintain .i files, and SWIG generates .c
files - Native MAPI support generated this way
- Pretty serious API, and it works a treat!
52SWIG and COM Client Interfaces2 of 3
- Sample .i from MAPI
- define TABLE_SORT_DESCEND TABLE_SORT_DESCENDHRES
ULT MAPIInitialize( MAPIINIT_0 INPUT)HRESULT
MAPILogonEx( ULONG INPUT, TCHAR
inNullString, ... IMAPISession OUTPUT)
53SWIG and COM Client Interfaces3 of 3
- Notes
- defines are carried into module
- Many functions are completely trivial
- SWIG handles input/output params
- Scope for even better integration with COM
- e.g., maybe the first cut at the .i could be
generated from the Type Info. - More work and discussions with Dave Beazley
needed!
54Using Python as a COM server
55Python COM ServersThe Problem
- Exposing a Python object as a COM object
- COM vtable C (not Python)
- IDispatch removes vtable requirement
- Imposes coding burden on client
- Some interfaces are defined as a vtable
- Answer we need an intermediary between COMs
vtables and a Python object - These are called gateways
56Gateways1 of 2
- Gateways act as the intermediary
- Hold reference to the Python object
- Map C method calls into Python calls
- Map parameters and return values
- A gateway is a C object implementing a
particular COM interface - Gateways are registered with the framework and
instantiated as needed to support particular
interfaces as they are requested
57Gateways2 of 2
- The default gateway supports IDispatch
- All Python COM servers automatically support
IDispatch - Default also supports ISupportErrorInfo, a
standard interface for returning extended error
information
58Gateways3 of 3
PythonCOM
Gateway
Wrapper
Server
Gateway
Client
Gateway
59Calling Python Methods
- The Python COM framework defines an
IDispatch-oriented protocol for how the gateways
call into Python - _QueryInterface_ determine support for a
particular COM interface - _GetIDsOfNames_ look up a dispatch identifier
(DISPID) for a given name - _Invoke_ invoke a method with specified
parameters
60Policies1 of 2
- Features of the gateway protocol
- Non-intuitive for a Python programmer
- Usually requires support structures for the
DISPID handling - Subtleties with some of the parameters and return
values - Result hard for Python programmers to write a
COM server - Answer policy objects
61Policies2 of 2
- A policy specifies how to implement a Python
COM server - The policy object maps the gateway protocol to
the given implementation policy - The default policy is usually sufficient
- Custom policies may be created and used
- An advanced topic (discussed later)
62Instantiation1 of 3
- The framework calls the CreateInstance function
in the win32com.server.policy module - Hard-wired call to CreateInstance, but behavior
can easily be hooked through custom policies - When your COM object is registered, an additional
registry key specifies the creator function - Typically mymodule.MyClass
63Instantiation2 of 3
- The registry key is read by the default policy
and used to instantiate your object - COM does not provide additional parameters to
your creator function (the __init__ method) - Make sure that any parameters have defaults
- COM will provide this capability
- Registry can specify a custom policy
64Instantiation3 of 3
PythonCOM
policy.py CreateInstance(clsid, riid)
clsid, riid
clsid, riid
returned
returned
creates
Interface
pUnk
65The Default Policy
- Python server objects (instances) are annotated
with special attributes - Typically specified as class attributes
- Most are optional
- _public_methods_
- A list of strings specifying the methods that
clients are allowed to call - This is the only required attribute
66A Quick Example
class MyPythonServer _public_methods_
SomeMethod def SomeMethod(self, arg1,
arg2) do_some_work(arg1) return
whatever(arg2)
- Note that the only difference for the Python
programmer is the addition of the
_public_methods_ attribute
67Useful Attributes
- _public_attrs_ what Python attributes should be
exposed as COM Properties - _readonly_attrs_ which of the above should be
considered read-only - _com_interfaces_ what COM interfaces beyond
IDispatch are supported
68Wrapping1 of 3
- The process of associating a gateway instance and
a policy instance with a particular Python
instance is known as wrapping - Similarly, retrieving the Python instance is
known as unwrapping - Objects returned by Python COM servers must be
wrapped (the framework does not automatically
wrap)
69Wrapping2 of 3
- This diagram shows the organization of the
- objects involved in a Python COM server and
- where the wrapping term came from
70Wrapping3 of 3
- Wrapping an object that will be returnedfrom
win32com.server import util...def method(self,
arg) ob whatever(arg) return util.wrap(ob) - Unwrapping (of an argument) is rare
- You must know the object is a Python object (and
what to do with it once unwrapped) - Usually used in relatively closed systems
71Error Handling1 of 3
- COM defines simple result codes with the HRESULT
type and associated constants - Extended error information includes description,
help file, context, etc - Returned via EXCEP_INFO structure in IDispatch or
through ISupportErrorInfo - Framework maps Python exceptions to COM result
codes and exceptions
72Error Handling2 of 3
- If the Python exception is an instance, then
framework looks for special attributes to fill in
COM extended exception information - Just raise an instance with the right attributes
- See exception.Exception utility class
- Otherwise, the framework does its best
73Error Handling3 of 3
- When called via IDispatch, it returns the
exception via EXCEP_INFO - For non-Dispatch calls, the caller may follow up
by using ISupportErrorInfo to retrieve the
exception - ISupportErrorInfo is part of the base gateway
class and is always present
74Collections1 of 3
- Collections are sequence-like objects that
typically implement the Add, Remove, and Item
methods and a Count property - Some Collections (such as those provided natively
by VB) can be indexed using numbers (acts as a
sequence) or using strings (acts as a mapping) - win32com.server.util.Collection is a simple
numerically indexed Collection class
75Collections2 of 3
- The Item method is special
- It should be the default method, meaning that
VB can implicitly call it without using its name - The predefined DISPID_VALUE value refers to the
default method - Item can be called with one parameter (the index)
or with two parameters (an index and a new value
to place at that index) - This duality is not handled well by the default
policy nor server.util.Collection - Also beware the numeric vs. string indexing
76Collections3 of 3
- The Python COM framework defines returning a list
or tuple to mean returning a SAFEARRAY of VARIANT
values - This means your object must explicitly return an
object that obeys the Collection protocol - A custom policy could be used to automatically
wrap sequences with a Collection - Only recognizes list and tuple
- avoids treating a string as a sequence
- instances are not checked for sequence behavior
77Enumerators1 of 3
- Enumerators are used by clients to enumerate a
collection (sequence) - VBScript automatically fetches an enumerator for
script code such as for each item in
collection - Standard COM protocol uses the predefined
DISPID_NEWENUM value and calls IDispatchInvoke()
- Default policy calls your _NewEnum method
78Enumerators2 of 3
- IEnumVARIANT is the interface used by Automation
clients (such as VB) - Your returned enumerator must implement the
IEnumVARIANT interface - Values returned from Next() are VARIANTs (see
client section for discussion of COM enumerator
interfaces) - Support for IEnumVARIANT part of core
- Python datatypes are easily coerced into VARIANTs
by the IEnumVARIANT gateway
79Enumerators3 of 3
- win32com.server.util.NewEnum(seq) will return an
enumerator for a given sequence - Custom enumerators are easily written
- Dynamic sequences
- Special handling of enumerated values
- Subclass from server.util.ListEnumerator,
ListEnumeratorGateway, or write from scratch - New gateways needed for interfaces other than
IEnumVARIANT
80Server Utilities
- Various functionality available in
win32com.server. - ...connect connection points
- ...exception exception handling
- ...policy framework support
- ...register server object registration
- ...util miscellaneous utilities
81win32com.server.connect
- Supplies utilities and classes for the server
side of connection points
82win32com.server.exception
- Exports a single class Exception
- Constructor has keyword arguments for the status
code, description, help file, etc. - The Exception class places these values into
instance variables - The Python COM framework picks up the values for
returning to the caller
83win32com.server.policy
- Framework knows about this file
- Hard-coded reference, so it must exist
- Provides CreateInstance for the framework
- Provides hooks for custom policies and
dispatchers - Defines various standard policies and dispatchers
- Future the policies and dispatchers will move
out to separate files for easier maintainability
84win32com.server.register
- Utilities for registering your COM servers
- Two primary functions
- RegisterServer()
- UnregisterServer()
- Typically, registration for servers in a file is
performed when the file is run from the command
line (e.g. python myservers.py) - RegisterServer() has many options see its doc
string for more information
85win32com.server.register Example
class MyClass _public_methods_ MyMethod
class definition if __name__
__main__ import sys from win32com.server
import register if len(sys.argv) gt 1 and
sys.argv1 --unregister register.Unregist
erServer(, The.ProgID) else register.Re
gisterServer(, MyModule.MyClass, progID
The.ProgID)
86win32com.server.util
- wrap()
- unwrap()
- NewEnum()
- ListEnumerator class
- ListEnumeratorGateway class
- Collection class
87win32com.makegw
- Tool for interfaces and gateways
- SWIG now my preference for interfaces - gateways
somewhat harder - Generate once, and never again
- compare with SWIG, which allows multiple
generations - particularly useful as support is
added after initial generation - Better than hand-coding
- Active Scripting, Debugging and some others done
this way
88Advanced Topics
89Advanced Dispatchers1 of 2
- Debugging and tracing utility
- Almost identical to policies simply delegate to
actual policy - Only used during development, so zero runtime
overhead in release - Implementation is not for speed, but for
assistance in debugging - e.g., IIDs translated if possible to names, often
using the registry or dictionary lookups, etc
90Advanced Dispatchers2 of 2
- Log information about your server
- All method calls made
- All IDispatch mapping
- All QueryInterface requests
- Dispatchers available that send to various
debugging terminals - win32dbg debugger, win32trace utility, existing
stdout, etc. - Easy to write your own if you have specific
debugging requirements
91Advanced Wrapping1 of 5
- All Python server objects are wrapped with at
least two objects the policy and the gateway - Caveat a custom policy may implement the actual
server rather than using another object (see
win32com.servers.dictionary) - Dispatchers can actually add a third layer into
this group
92Advanced Wrapping2 of 5
- Since a gateway is referenced with a C
interface pointer, Python cannot hold the
reference - Wrap once more with a framework interface
(well call it a PyInterface to distinguish from
COM interfaces) - The PyInterface is removed by the framework
(exposing the C pointer) when a PyInterface is
returned by a server
93Advanced Wrapping3 of 5
Interface
Python
C
Returned to COM client (the framework removes the
PyInterface)
94Advanced Wrapping4 of 5
- win32com.pythoncom.WrapObject() wraps a Python
object with a gateway and a PyInterface - Pass it the policy object (which is wrapping the
Python server object) - Optional parameter specifies the IID of a gateway
to use for the wrapping (the gateway must be
registered with the COM framework)
95Advanced Wrapping5 of 5
- Unwrapping is performed through a special COM
interface IUnwrapPythonObject - pythoncom.UnwrapObject() queries for this
interface on the COM object held within the
PyInterface object that is passed - The base gateway class implements this COM
interface (so all gateways have it) - The interfaces single method returns the
gateways underlying Python object
96Advanced Custom Policies1 of 7
- Why use a custom policy?
- Special error handling, creation, calling
mechanisms, validation, etc - Write the policy class and enter the appropriate
information into the registry so that the
framework will use your policy - Be sure to use your custom policy when wrapping
your objects
97Advanced Custom Policies2 of 7
- Other provided policies
- BasicWrapPolicy handy base class
- MappedWrapPolicy low level mapping-based
handling of names and properties and methods - DesignatedWrapPolicy build onto the Mapped
policy a way for objects to easily specify the
properties and methods - DynamicPolicy determine methods and properties
dynamically
98Advanced Custom Policies3 of 7
- Example custom instantiation
- A single Python COM server was used to represent
multiple COM objects - At instantiation time, it used the CLSID passed
to the policy to look in the registry for more
detailed information - A child/sub object was created, based on the
registered information the COM server provided
some generic behavior for all of the child objects
99Advanced Custom Policies4 of 7
- Example error handling
- Returning KeyError or other Python exceptions
to callers was undesirable - Wrap all Invokes with an exception handler that
would map Python errors into a generic error - Let through pythoncom.com_error unchanged
- If a magic registry value was present, then a
full traceback was placed into the exception
(rather than simply internal error)
100Advanced Custom Policies5 of 7
- Example data validation
- If the server object had a _validation_map_
attribute, then a custom validation method would
be called for all Property puts - _validation_map_ would map a Property name to a
type signature that the _validate_() method would
test against - The Invoke method was hooked to call the
_validate_() method
101Advanced Custom Policies6 of 7
- Example functions for Property get/put
- The Item() method in Collections is really
treated as a parameterized property - Using a custom policy, get_Item() can be
differentiated from put_Item() - Allowed for get_Count() and the absence of
put_Count() implied read-only
102Advanced Custom Policies7 of 7
- Example alter mechanism for specifying the
available properties - Using the _validation_map_ from a previous
example, the available properties are easily
derived (simply the keys of the mapping) - Avoided duplication of property specification
(one in _validation_map_ and one in
_public_attrs_)
103Advanced Threading1 of 2
- Python is normally single threaded the least
capable COM threading model - With care, it could be possible to mark an object
as free threaded to fool how COM handles the
object, but Python will continue to allow only
one thread per process to run - This behavior is fine for many applications where
Python is a COM client, but it breaks down for
some server scenarios
104Advanced Threading2 of 2
- The problem can be reduced by applying patches
with allow Python to be truly free-threaded - Slows down single thread case
- Applies mainly to multiprocessor use
- More work on threading is needed and is in
progress on the Thread-SIG
105Futures
106Future Directions
- Auto wrap and unwrap
- COM
- SWIG
- makepy
107Future Auto Wrapping
- This could be done today, but wasnt
- Leaving it to Python increased flexibility
- Complexity involved with needing a way to specify
two things during any wrapping process the
policy and the gateway - Moving to COM will be an opportune time to
change - Annotation through attributes will control
wrapping process
108Future COM1 of 3
- What is COM ?
- Upcoming revision of COM
- Runtime services memory management,
interceptors, object model changes, language
independence, etc - see http//www.microsoft.com/cominfo
109Future COM2 of 3
- Python already has most of COMs facilities and
matches its model strongly - Huge win for Python
- Simplify COM programming even more
- Will reduce the framework and associated
overheads - Better language compatibilities
- Major reduction in dependence on vtables
- Better type handling
110Future COM3 of 3
- Any Python object can be a COM server, provided
it is registered appropriately - Note that COM registration will be easier
- Auto wrapping
- import somedll will load the metadata from
the DLL and automatically make its classes and
constants available
111Future SWIG
- Depends largely on what Dave Beazley is willing
to support! - Interface support needs more work
- Framework is OK
- Mainly adding all interfaces and types to SWIG
library - Gateways still a long way off
- Future here quite uncertain
- Some sort of IDL parsing highly desirable
112Future makepy
- Functionally quite complete
- Some cleanup desirable, but works well
- Architectural issues outstanding
- Where does generated code go?
- Utilities for automatic generation
- From program ID
- Integration with COM browser
- Integration with some GUI interface