Post

GSoC 2025 - Week 4

The styles related changes are completed earlier this week and PR #888 is merged.

After thinking about how to add Annotations support in the most extensible way possible and quite a bit of learning and prototyping, I started this disussion #889 and outlined the high level approach. I have the basic approach that provides extensibility for annotations working. With this, user created custom annotations should work the same way as the ones we provide with Molecular Nodes. The overall changes needed for Annotations support are quite a lot, so I am a bit further away from having an actual PR this week.

There are quite a few learnings this week:

  • Learnt about the factory pattern and how this can help with the different annotation types (including custom user created ones) that we support
  • Python provides several ways to automatically register subclasses - using __new__ in the metaclass or using __init_subclass__, each with subtle differences - the later is what I chose to use in our case
  • A dynamic method can be created the same as an attribute using setattr - methods can be added to a class this way. types.MethodType is needed if methods are needed for specific instances. We will use the former
  • partial and partialmethod of functools (the former is for functions and the later is for methods in a class) provide a way to fix certain inputs and return new functions or methods respectively. We can use the functools.partialmethod to fix the self input of an instance method when creating a custom method from a class method (@classmethod) which doesn’t have access to an instance. This will allow us to create custom methods to create corresponding annotation instance (like add_atom_info to add an atom info annotation as opposed to a generic factory method to create these instances)
  • Python’s inspect module provides a get_annotations to get the python specific annotations defined for an object - this is the equivalent of accessing the __annotations__ attribute directly, but this is the recommended way. We use this to determine inputs for the annotation type classes
  • inspect also has a signature to get the signature of any callable. There are ways to set the __signature__ attribute to any custom signature (either copied from other methods or creating completely new ones using other inspect classes). Though this works in general, I wasn’t able to get this working This also works for our case with the partialmethod approach above when creating an annotation instance - for auto-complete support in Jupyter notebooks or VSCode
  • Learnt about the AnalysisFromFunction, analysis_class and MDAnalysis.analysis.base.AnalysisBase approaches in MDAnalysis for creating custom analysis classes

Next week, I will continue working on the Annotations support.

This post is licensed under CC BY 4.0 by the author.