So... it's been an interesting week. After my last contribution to Scikit-learn (which was honestly pretty straightforward), I wanted to find something a bit more challenging. Something that would actually make me think, maybe?
I've been getting more into Machine Learning(ML) lately, especially pipelines and orchestration stuff. That's when I found Dagster.
What is Dagster?
If you're not familiar, Dagster is a data orchestration platform. Think of it like this. When you're building ML pipelines or data workflows, you need something to coordinate all the different steps such as fetching data, transforming it, training models, deploying them, and etc. Dagster helps you organize all of that massive work into something manageable size.
What caught my attention is that it is actually used in production by real companies. This isn't some hobby project. Plus, it has a really active community and the codebase is actually pretty readable.
Finding the Issue
I was browsing through their GitHub issues, I found Issue #32574: "Callable object custom signatures are resolved incorrectly."
Issue-32574
At first glance, I thought "Oh cool, this looks easy." But then I read the details and realized this was actually pretty interesting.
The Problem
Here's the deal: Python has this cool feature where you can create callable objects (basically, classes with a __call__ method) that act like functions. You can even give them custom signatures using the __signature__ attribute. This is super useful for decorators and wrappers that need to preserve type information.
But Dagster's get_type_hints() function wasn't handling this correctly. When you had something like this:
class MyWrapper:
def __init__(self, fn):
# Set custom signature
self.__signature__ = inspect.signature(fn)
def __call__(self, **kwargs):
# Generic signature
...
The code would crash with:
TypeError: <callable object> is not a module, class, method, or function.
Why? Because the code was trying to pass the callable instance directly to Python's typing.get_type_hints(), which doesn't know how to handle arbitrary objects. It only works with actual functions, classes, and modules.
The Solution
The fix was actually straight forward once I understood the problem. Instead of passing the object to typing.get_type_hints(), you should extract the type information directly from the __signature__ object.
if hasattr(fn, "__signature__"):
sig = fn.__signature__
hints = {}
for param_name, param in sig.parameters.items():
if param.annotation != inspect.Parameter.empty:
hints[param_name] = param.annotation
if sig.return_annotation != inspect.Signature.empty:
hints['return'] = sig.return_annotation
return hints # Return immediately!
The signature object already has all the type information you need which means that you can simply extract it.
Testing
One of the most important procedure of open source contribution is testing. I created test_sensor_invocation_resources_callable_with_custom_signature() which basically does exactly what the issue described.
Creates a callable object with a custom `__signature__`
Verifies that `Dagster` can now correctly read the type hints
Confirms that resources are properly recognized.
Once the code passed the test, I ran the entire test suite to make sure I didn't break anything. All 52 tests in test_sensor_invocation.py passed. That's always a good feeling.

What I Learned
This contribution taught me way more than just "fix this bug".
Python's Signature Protocol: I had no idea Python had such a sophisticated system for custom signatures. The __signature__ attribute is part of the standard library and is specifically designed for cases like this.
Testing is Critical: In a production system like Dagster, you can't just "fix it and good to go." I had to make sure my change didn't break any existing functionality. The test suite is your safety net.
Reading Complex Codebases: This required understanding how Dagster's decorator system works, how it resolves resources, and how the whole dependency injection mechanism functions. It was challenging but super rewarding.
I'm really enjoying this open source contribution journey. Each project teaches me something new. If you're thinking about contributing to open source, my advice is, don't be afraid to tackle issues that seem a bit over your head. You'll realize you are not as stupid as you think you are. Just make sure you understand the problem and the project before you start coding.
Top comments (0)