Details
-
Type:
Story
-
Status: Done
-
Resolution: Done
-
Fix Version/s: None
-
Component/s: utils
-
Labels:None
-
Story Points:4
-
Epic Link:
-
Sprint:DRP S17-3
-
Team:Data Release Production
Description
Our codebase is full of template classes that are wrapped into a set of Python classes with suffixes derived from their template type (e.g. ImageF, ImageD, ImageU).
In some places, we've defined a module scoped dictionary with the un-suffixed name to relate these, e.g. afw.table.Key["F"] is afw.table.KeyF.
To enhance both the usuability of our Python interfaces and the ease of writing wrappers, we should:
- Add an Abstract Base Class for each of these template classes (https://docs.python.org/2/library/abc.html), making it appear as though all template instantiations inherit from the same class (in e.g. isinstance checks).
- Make these ABCs inherit from a custom metaclass (which in turn inherits from abc.ABCMeta) that allows dict-like access to the registered instantiations from both the string suffixes and the corresponding numpy types (e.g. numpy.float32 for "F"), preserving the dict behavior mentioned above.
- Add a __new__ method to each ABC that accepts a dtype argument and forwards all other arguments to the constructor of the wrapped template the dtype key points to. In other words, make e.g. Image(bbox, dtype=numpy.float32) call ImageF(bbox). We could probably have the metaclass inject this automatically.
New users to the stack should be able to mostly get by without seeing the templated types at all - they'd only interact with the ABC. And devs writing the Python wrappers for templated classes could define pure-Python extensions directly in the ABC instead of monkeypatching them into each wrapped template.
This issue covers adding the metaclass to utils and demonstrating its use in at least one template class wrapper. Using it for other classes could be done on other pybind11 branches, as it strictly represents an addition to the API, and it could be useful to do it there as to get the monkeypatching-avoidance mentioned above.
In addition to the above, this ticket should include an implementation for the decorators described in RFC-270, which have significant code in common with the metaclass (as implemented currently) and a related purpose.
Attachments
Issue Links
- blocks
-
DM-9099 Begin cleanup of pybind11 branch
- Done
-
DM-8716 Use visitor pattern to clean up afw::table pybind11 wrappers
- Done
- is triggered by
-
RFC-270 Decorators for adding Python code to wrapped C++ classes
- Implemented
- relates to
-
RFC-270 Decorators for adding Python code to wrapped C++ classes
- Implemented
Activity
Field | Original Value | New Value |
---|---|---|
Story Points | 1 | 2 |
Assignee | Jim Bosch [ jbosch ] | Pim Schellart [ pschella ] |
Description |
Our codebase is full of template classes that are wrapped into a set of Python classes with suffixes derived from their template type (e.g. {{ImageF}}, {{ImageD}}, {{ImageU}}).
In some places, we've defined a module scoped dictionary with the un-suffixed name to relate these, e.g. {{afw.table.Key\["F"\] is afw.table.KeyF}}. To enhance both the usuability of our Python interfaces and the ease of writing wrappers, we should: - Add an Abstract Base Class for each of these template classes (https://docs.python.org/2/library/abc.html), making it appear as though all template instantiations inherit from the same class (in e.g. {{isinstance}} checks). - Make these ABCs inherit from a custom metaclass (which in turn inherits from {{abc.ABCMeta}}) that allows dict-like access to the registered instantiations from both the string suffixes and the corresponding numpy types (e.g. {{numpy.float32}} for "F"), preserving the dict behavior mentioned above. - Add a {{\_\_new\_\_}} method to each ABC that accepts a {{dtype}} argument and forwards all other arguments to the constructor of the wrapped template the {{dtype}} key points to. In other words, make e.g. {{Image(bbox, dtype=numpy.float32)}} call {{ImageF(bbox)}}. We could probably have the metaclass inject this automatically. New users to the stack should be able to mostly get by without seeing the templated types at all - they'd only interact with the ABC. And devs writing the Python wrappers for templated classes could define pure-Python extensions directly in the ABC instead of monkeypatching them into each wrapped template. This issue covers adding the metaclass to utils and demonstrating its use in at least one template class wrapper. Using it for other classes could be done on other pybind11 branches, as it strictly represents an addition to the API, and it could be useful to do it there as to get the monkeypatching-avoidance mentioned above. |
Our codebase is full of template classes that are wrapped into a set of Python classes with suffixes derived from their template type (e.g. {{ImageF}}, {{ImageD}}, {{ImageU}}).
In some places, we've defined a module scoped dictionary with the un-suffixed name to relate these, e.g. {{afw.table.Key\["F"\] is afw.table.KeyF}}. To enhance both the usuability of our Python interfaces and the ease of writing wrappers, we should: - Add an Abstract Base Class for each of these template classes (https://docs.python.org/2/library/abc.html), making it appear as though all template instantiations inherit from the same class (in e.g. {{isinstance}} checks). - Make these ABCs inherit from a custom metaclass (which in turn inherits from {{abc.ABCMeta}}) that allows dict-like access to the registered instantiations from both the string suffixes and the corresponding numpy types (e.g. {{numpy.float32}} for "F"), preserving the dict behavior mentioned above. - Add a {{\_\_new\_\_}} method to each ABC that accepts a {{dtype}} argument and forwards all other arguments to the constructor of the wrapped template the {{dtype}} key points to. In other words, make e.g. {{Image(bbox, dtype=numpy.float32)}} call {{ImageF(bbox)}}. We could probably have the metaclass inject this automatically. New users to the stack should be able to mostly get by without seeing the templated types at all - they'd only interact with the ABC. And devs writing the Python wrappers for templated classes could define pure-Python extensions directly in the ABC instead of monkeypatching them into each wrapped template. This issue covers adding the metaclass to utils and demonstrating its use in at least one template class wrapper. Using it for other classes could be done on other pybind11 branches, as it strictly represents an addition to the API, and it could be useful to do it there as to get the monkeypatching-avoidance mentioned above. In addition to the above, this ticket should include an implementation for the decorators described in |
Summary | Metaclass for wrapped-template ABCs | Metaclass for wrapped-template ABCs and class extension decorators |
Assignee | Pim Schellart [ pschella ] | Jim Bosch [ jbosch ] |
Story Points | 2 | 4 |
Sprint | DRP S17-3 [ 360 ] |
Status | To Do [ 10001 ] | In Progress [ 3 ] |
Reviewers | Krzysztof Findeisen [ krzys ] | |
Status | In Progress [ 3 ] | In Review [ 10004 ] |
Reviewers | Krzysztof Findeisen [ krzys ] | Nate Lust [ nlust ] |
Status | In Review [ 10004 ] | Reviewed [ 10101 ] |
Resolution | Done [ 10000 ] | |
Status | Reviewed [ 10101 ] | Done [ 10002 ] |
I'm all in favor of a dtype option (I pushed for such a thing in May 2015). Be careful about the differences between Python 2 and 3 when using metaclasses.