enthought / enthought/comtypes

Proposal: registering servers by class rather than by file

Open
#312 0 comments 1 reaction 0 assignees View on GitHub
enhancement
Dominant language
Python
Stars
345
Forks
105
PR merge metrics
No merged PRs in 30d

Description

I have a comtypes use case where I am implementing a plugin style architecture over COM (each plugin is a separate COM server implementing the same interface). To allow the plugins to work asynchronously to the main app, I use a 2 thread approach whereby COM method calls on the principal object are passed on to a worker object in a second thread (allowing the original COM method to return immediately while processing is done).

Plugins are implemented by subclassing the worker thread and applying a decorator which internally creates a subclass of the COM server class with the single change of which worker class it will use. This is convenient because it abstracts away the COM details which are always the same, but the problem is that the class' __module__ and __file__ end up being those of the base COM server, not the worker subclass, so when registering the different classes they all end up with the same calling signature of baseserver.py, with no way to determine which class to actually instantiate when launching.

pywin32/pythoncom has the same issue, but they have solved it by adding an extra property _reg_class_spec_ to registerable classes which allows specifying the actual class to instantiate when launching a local server. It would be really nice to allow this use case in comtypes, although I recognise that the current method is useful in different circumstances.

What I would propose is to allow an additional property (which could be _reg_class_spec_ or some similar name) which, when present on a class being registered, would change the registered launch signature going into the registry LocalServer32 key to look like
```
path\to\python.exe \path\to\comtypes\localserver.py -c _reg_class_spec
```
where localserver.py gets an extra section at the bottom
```
if __name__ == "__main__":
class_name = parse_class_name(sys.argv)
cls = lookup_class_from_name(class_name)
run((cls,))
```
I have tested this locally and it works well, but I wanted to get maintainer opinions and some discussion about exactly how we might want this implemented before submitting a PR: obviously there are some choices about how we might define the exact interface in terms of variable names etc.

Note that this change would be opt-in in the sense that there is only a change in behaviour if the new property is set on the class being registered. Let me know what you think.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.