Conversation
Type to_rack return as a precise tuple [Integer, Hash[String, String], Array[String]] instead of Array[untyped]. The values come directly from the status, headers, and body attr_readers which are already typed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Typing analysisIgnored filesThis PR clears 3 ignored files. It increases the percentage of typed files from 45.64% to 45.97% (+0.33%). Ignored files (+0-3)✅ Cleared:Note: Ignored files are excluded from the next sections.
|
Define Rack::env, Rack::response, and Rack::app type aliases in vendor/rbs/rack/0/rack.rbs and use them consistently across all Rack middleware signatures: AppSec (Rack, Rails, Sinatra, Devise), Tracing (Rack, Rails, Sinatra, Hanami). Replaces inline Hash[String, untyped] env parameters, untyped app fields, and untyped call return types with the shared aliases. Removes duplicate local type definitions from Sinatra middleware. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add type annotations to narrow http_response from Rack::response? to Rack::response, allowing the RBS signature to be precise without the nullable workaround. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rails ExceptionMiddleware and Hanami ActionTracer now pass steep checks with the new Rack types. Add missing @action ivar declaration to ActionTracer. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use local variable for active_span so Steep can narrow the type through the && guard. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
✅ Tests 🎉 All green!❄️ No new flaky tests detected 🎯 Code Coverage (details) 🔗 Commit SHA: dbab7cb | Docs | Datadog PR Page | Was this helpful? React with 👍/👎 or give us feedback! |
BenchmarksBenchmark execution time: 2026-03-18 00:42:54 Comparing candidate commit dbab7cb in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 46 metrics, 0 unstable metrics.
|
Strech
left a comment
There was a problem hiding this comment.
I like how you make it better for everyone! 💟
The only concern I have - it's better to type less, than type it false, as the consequences are - false feeling of being safe.
Rack env values are intentionally polymorphic (any user data can appear there), and the middleware options hash is an open config map — both should use `any`, not `untyped`. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Use Response::_Body interface for response body instead of Array[String]; plain arrays still satisfy the interface but body proxy objects are now also accepted - Restore the _Body interface definition that was dropped - Fix params to use `any` since request param values are intentionally polymorphic Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| @app: ::Rack::app | ||
|
|
||
| def initialize: (untyped app, ?::Hash[untyped, untyped] opt) -> void | ||
| def initialize: (::Rack::app app, ?::Hash[::Symbol, any] opt) -> void |
There was a problem hiding this comment.
Can you keep it as untyped here, not sure about any
| def initialize: (::Rack::app app, ?::Hash[::Symbol, any] opt) -> void | |
| def initialize: (::Rack::app app, ?::Hash[::Symbol, untyped] opt) -> void |
There was a problem hiding this comment.
I did some research and i added a typing interface for Rack middlewares:
dd-trace-rb/vendor/rbs/rack/0/rack.rbs
Lines 22 to 34 in fac1ec9
So the options are up to the choice of the middleware itself, and in this case, there should be no option after the rack app.
I updated all the types to match, and left some to-do's to remove the unused opt where that occurs.
I'm not going to remove the argument in this PR because I think that there's a minor chance that it needs extra testing.
Strech
left a comment
There was a problem hiding this comment.
To unblock this PR from being merged, I'm approving this
But also, I would like to ask for few changes in lib/appsec typespecs and vendor/rack
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add Rack::Middleware and Rack::MiddlewareWithOptions[T] modules to vendor/rbs/rack/0/rack.rbs as shared type-only signatures - Apply Rack::Middleware to RequestBodyMiddleware, Rails::RequestMiddleware, and Sinatra::RequestMiddleware RBS files - Add TODO + steep:ignore for unused opt arg in all three Ruby files Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
What does this PR do?
Defines shared
Rack::env,Rack::response, andRack::apptype aliases invendor/rbs/rack/0/rack.rbsand applies them consistently across all Rack middleware RBS signatures.Motivation:
Every Rack middleware follows the same contract:
call(env) -> [status, headers, body]. Previously, each signature either repeated::Hash[::String, untyped]inline or useduntypedfor the env, app, and response. This centralizes the Rack types so all middleware use the same vocabulary.Change log entry
None.
Additional Notes:
RBS-only changes, no runtime code modified. Several middleware lib files remain in the Steepfile ignore list due to pre-existing issues unrelated to these type changes.
How to test the change?
bundle exec steep check lib/datadog/appsec/response.rb lib/datadog/appsec/contrib/sinatra/request_middleware.rb lib/datadog/appsec/contrib/rack/request_body_middleware.rb lib/datadog/appsec/contrib/rails/request_middleware.rb