Implementing IPersistStorage using PythonCOM

Edward Blakes eblakes at
Thu Dec 7 18:50:00 EST 2000

Hi all,

I am having a problem creating a COM server that implements IPersistStorage.
Below is the code for the server. I am using ActivePython build 202.

I have removed the bodies of the function members to keep this posting as
small as possible. Also, they do not seem to be the root of the problem.
After the code I have some additional information about the problem.

Here is the code.

CATID_PerspectiveAttributeTypeServer = pythoncom.MakeIID("{a guid}")
CLSID_PythonSample = pythoncom.MakeIID("{a guid}")

class DummyAttr:
    SampleProperty = ""

    _public_attrs_ = ["SampleProperty"]
    _public_methods_ = ["DoSomething", "GetClassID", "IsDirty", "InitNew",
"Load", "Save", "SaveCompleted", "HandsOffStorage"]
    _reg_clsid_ = CLSID_PythonSample
    _reg_progid_ = "PerspectiveAttribute.PythonSample"
    _reg_catids_ = [CATID_PerspectiveAttributeTypeServer]
    _com_interfaces_ = [pythoncom.IID_IPersist,

    def __init__(self):
    def DoSomething(self):
    def GetClassID(self):
    def IsDirty(self):
    def InitNew(self):
    def Load(self, pStg):
    def Save(self, pStg, fSameAsLoad):
    def SaveCompleted(self, pStg):
    def HandOffStorage(self):

class LockBytes:
... (An almost exact copy of the class in for testing only)

def Test():
    import win32com.client
    import win32com.server.util

    # Create the server
    origObj = DummyAttr()
    aServer = win32com.server.util.wrap(origObj,
    # Test persistence
    aLockBytes = win32com.server.util.wrap(LockBytes(),
    pStg = pythoncom.StgCreateDocfileOnILockBytes(aLockBytes,

    origObj.Save(pStg,1)   <--- This is works.
    aServer.Save(pStg, 1)  <--- This fails with the traceback

def Register():
    from win32com.server.register import UseCommandLine
    return UseCommandLine(DummyAttr)

if __name__ == '__main__':
    import sys
    if "/test" in sys.argv:
        print "Testing..."

End code.

When running the code in "test" mode I get the following traceback message.
Note that the line numbers won't match because I was using the original

Traceback (most recent call last):
  File "", line 176, in ?
     File "", line 158, in Test
      aServer.Save(pStg, 1)
   pywintypes.com_error: (-2147352573, 'Member not found.', (0, None,
'Member not found', None, 0, -2147352573), None)

When stepping through the code in the PythonWin debugger, stepping into
aServer.Save() goes to a method that looks like something that implements
IDispatch::Invoke(). Not what I expect, even though aServer is a
PyIPersistStorage. A dir(aServer) (and, coincidentally a dir(origObj)) shows
a method named Save.

When I create the server using another client (C++), I get error 0x80020003
(which matches the traceback) when using IPersistStorage::Save() or
IPersistStorage::Load(). The server is instantiated without incident and the
QueryInterface for IID_IPersistStorage works perfectly. Category
registration works well, too. (The component category registration support
is sweet! This is not something VB can do on its own.)

Admittedly, I am a newbie to Python, though not a newbie to COM. This is
probably a more ambitious project than a newbie should tackle but I have a
specific need to build a automation server that can persist to IStorage but
is easily and quickly modifiable. Python fits the bill. I'd appreciate any
help in figuring this one out. I just don't see what I am doing wrong.

Thanks in advance for any help.

Ed Blakes
eblakes at

More information about the Python-list mailing list