I think the persistent_id interface is a poor match for you are attempting to do. It is designed to be used when your object should refer to equivalent objects on the new program rather then copies of the old one. You are attempting to filter out every object that cannot be pickled which is different and why are you attempting to do this.
I think this is a sign of problem in your code. That fact that you want to pickle objects which refer to gui widgets, files, and locks suggests that you are doing something strange. The kind of objects you typically persist shouldn't be related to or hold references to that sort of object.
Having said that, I think your best option is the following:
class MyPickler(Pickler):
def save(self, obj):
try:
Pickler.save(self, obj)
except PicklingEror:
Pickle.save( self, FilteredObject(obj) )
This should work for the python implementation, I make no guarantees as to what will happen in the C implementation. Every object which gets saved will be passed to the save method. This method will raise the PicklingError when it cannot pickle the object. At this point, you can step in and recall the function asking it to pickle your own object which should pickle just fine.
EDIT
From my understanding, you have essentially a user-created dictionary of objects. Some objects are picklable and some aren't. I'd do this:
class saveable_dict(dict):
def __getstate__(self):
data = {}
for key, value in self.items():
try:
encoded = cPickle.dumps(value)
except PicklingError:
encoded = cPickle.dumps( Unpickable() )
return data
def __setstate__(self, state):
for key, value in state:
self[key] = cPickle.loads(value)
Then use that dictionary when you want to hold that collection of objects. The user should be able to get any picklable objects back, but everything else will come back as the Unpicklable() object. The difference between this and the previous approach is in objects which are themselves pickable but have references to unpicklable objects. But those objects are probably going to come back broken regardless.
This approach also has the benefit that it remains entirely within the defined API and thus should work in either cPickle or pickle.