Skip to content

Commit 4b5d8ba

Browse files
chore: fix interceptor type errors
1 parent 389a327 commit 4b5d8ba

10 files changed

Lines changed: 72 additions & 26 deletions

File tree

temporalio/.rubocop.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,24 @@ Style/Documentation:
8080
Enabled: true
8181
Exclude:
8282
- lib/temporalio/internal/**/*
83+
- extra/sorbet_check/**/*
8384

8485
# We want methods to be documented
8586
Style/DocumentationMethod:
8687
Enabled: true
8788
Exclude:
8889
- lib/temporalio/internal/**/*
90+
- extra/sorbet_check/**/*
91+
92+
# Sorbet check file uses extend T::Sig at top level
93+
Style/MixinUsage:
94+
Exclude:
95+
- extra/sorbet_check/**/*
96+
97+
# Sorbet check file defines multiple stub classes in one file
98+
Style/OneClassPerFile:
99+
Exclude:
100+
- extra/sorbet_check/**/*
89101

90102
# Ok to have global vars in tests
91103
Style/GlobalVars:

temporalio/Gemfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ gemspec
66

77
group :development do
88
gem 'activemodel'
9-
gem 'rbi'
10-
gem 'sorbet-runtime'
119
gem 'activerecord'
1210
gem 'async'
1311
gem 'base64'
@@ -24,10 +22,12 @@ group :development do
2422
gem 'opentelemetry-sdk'
2523
gem 'rake'
2624
gem 'rake-compiler'
25+
gem 'rbi'
2726
gem 'rbs', '~> 3.10'
2827
gem 'rb_sys', '~> 0.9'
2928
gem 'rdoc'
3029
gem 'rubocop'
30+
gem 'sorbet-runtime'
3131
gem 'sqlite3'
3232
gem 'steep', '~> 1.10'
3333
gem 'yard'

temporalio/Steepfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ end
2424
target :test do
2525
signature 'sig', 'test/sig'
2626
check 'test'
27+
ignore 'test/support'
2728
library 'uri', 'objspace'
2829
configure_code_diagnostics do |hash|
2930
hash.update(common_diagnostics)

temporalio/rbi/temporalio.rbi

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4209,10 +4209,10 @@ class Temporalio::Client::Interceptor::ReportCancellationAsyncActivityInput < ::
42094209
end
42104210

42114211
class Temporalio::Client::Interceptor::Outbound
4212-
sig { params(next_interceptor: T.nilable(Temporalio::Client::Interceptor::Outbound)).void }
4212+
sig { params(next_interceptor: Temporalio::Client::Interceptor::Outbound).void }
42134213
def initialize(next_interceptor); end
42144214

4215-
sig { returns(T.nilable(Temporalio::Client::Interceptor::Outbound)) }
4215+
sig { returns(Temporalio::Client::Interceptor::Outbound) }
42164216
def next_interceptor; end
42174217

42184218
sig { params(input: Temporalio::Client::Interceptor::StartWorkflowInput).returns(Temporalio::Client::WorkflowHandle) }
@@ -4967,10 +4967,10 @@ end
49674967
class Temporalio::Worker::Interceptor::Activity::Inbound
49684968
extend T::Sig
49694969

4970-
sig { returns(T.nilable(Temporalio::Worker::Interceptor::Activity::Inbound)) }
4970+
sig { returns(Temporalio::Worker::Interceptor::Activity::Inbound) }
49714971
def next_interceptor; end
49724972

4973-
sig { params(next_interceptor: T.nilable(Temporalio::Worker::Interceptor::Activity::Inbound)).void }
4973+
sig { params(next_interceptor: Temporalio::Worker::Interceptor::Activity::Inbound).void }
49744974
def initialize(next_interceptor); end
49754975

49764976
sig { params(outbound: Temporalio::Worker::Interceptor::Activity::Outbound).returns(Temporalio::Worker::Interceptor::Activity::Outbound) }
@@ -4983,10 +4983,10 @@ end
49834983
class Temporalio::Worker::Interceptor::Activity::Outbound
49844984
extend T::Sig
49854985

4986-
sig { returns(T.nilable(Temporalio::Worker::Interceptor::Activity::Outbound)) }
4986+
sig { returns(Temporalio::Worker::Interceptor::Activity::Outbound) }
49874987
def next_interceptor; end
49884988

4989-
sig { params(next_interceptor: T.nilable(Temporalio::Worker::Interceptor::Activity::Outbound)).void }
4989+
sig { params(next_interceptor: Temporalio::Worker::Interceptor::Activity::Outbound).void }
49904990
def initialize(next_interceptor); end
49914991

49924992
sig { params(input: Temporalio::Worker::Interceptor::Activity::HeartbeatInput).void }
@@ -5067,10 +5067,10 @@ end
50675067
class Temporalio::Worker::Interceptor::Workflow::Inbound
50685068
extend T::Sig
50695069

5070-
sig { returns(T.nilable(Temporalio::Worker::Interceptor::Workflow::Inbound)) }
5070+
sig { returns(Temporalio::Worker::Interceptor::Workflow::Inbound) }
50715071
def next_interceptor; end
50725072

5073-
sig { params(next_interceptor: T.nilable(Temporalio::Worker::Interceptor::Workflow::Inbound)).void }
5073+
sig { params(next_interceptor: Temporalio::Worker::Interceptor::Workflow::Inbound).void }
50745074
def initialize(next_interceptor); end
50755075

50765076
sig { params(outbound: Temporalio::Worker::Interceptor::Workflow::Outbound).returns(Temporalio::Worker::Interceptor::Workflow::Outbound) }
@@ -5383,10 +5383,10 @@ end
53835383
class Temporalio::Worker::Interceptor::Workflow::Outbound
53845384
extend T::Sig
53855385

5386-
sig { returns(T.nilable(Temporalio::Worker::Interceptor::Workflow::Outbound)) }
5386+
sig { returns(Temporalio::Worker::Interceptor::Workflow::Outbound) }
53875387
def next_interceptor; end
53885388

5389-
sig { params(next_interceptor: T.nilable(Temporalio::Worker::Interceptor::Workflow::Outbound)).void }
5389+
sig { params(next_interceptor: Temporalio::Worker::Interceptor::Workflow::Outbound).void }
53905390
def initialize(next_interceptor); end
53915391

53925392
sig { params(input: Temporalio::Worker::Interceptor::Workflow::CancelExternalWorkflowInput).void }

temporalio/rbs_collection.lock.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ gems:
153153
version: '0'
154154
source:
155155
type: stdlib
156+
- name: prism
157+
version: 1.9.0
158+
source:
159+
type: rubygems
156160
- name: pstore
157161
version: '0'
158162
source:

temporalio/sig/temporalio/client/connection.rbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ module Temporalio
99
attr_reader rpc_retry: RPCRetryOptions
1010
attr_reader identity: String
1111
attr_reader keep_alive: KeepAliveOptions
12-
attr_reader http_connect_proxy: HTTPConnectProxyOptions?
12+
attr_reader http_connect_proxy: HTTPConnectProxyOptions
1313
attr_reader runtime: Runtime
1414
attr_reader lazy_connect: bool
1515

temporalio/sig/temporalio/client/interceptor.rbs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,9 +433,9 @@ module Temporalio
433433
end
434434

435435
class Outbound
436-
attr_reader next_interceptor: Outbound?
436+
attr_reader next_interceptor: Outbound
437437

438-
def initialize: (Outbound? next_interceptor) -> void
438+
def initialize: (Outbound next_interceptor) -> void
439439

440440
def start_workflow: (StartWorkflowInput input) -> WorkflowHandle
441441

temporalio/sig/temporalio/worker/interceptor.rbs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ module Temporalio
2020
end
2121

2222
class Inbound
23-
attr_reader next_interceptor: Inbound?
23+
attr_reader next_interceptor: Inbound
2424

25-
def initialize: (Inbound? next_interceptor) -> void
25+
def initialize: (Inbound next_interceptor) -> void
2626

2727
def init: (Outbound outbound) -> Outbound
2828

@@ -37,9 +37,9 @@ module Temporalio
3737
end
3838

3939
class Outbound
40-
attr_reader next_interceptor: Outbound?
40+
attr_reader next_interceptor: Outbound
4141

42-
def initialize: (Outbound? next_interceptor) -> void
42+
def initialize: (Outbound next_interceptor) -> void
4343

4444
def heartbeat: (HeartbeatInput input) -> void
4545
end
@@ -105,9 +105,9 @@ module Temporalio
105105
end
106106

107107
class Inbound
108-
attr_reader next_interceptor: Inbound?
108+
attr_reader next_interceptor: Inbound
109109

110-
def initialize: (Inbound? next_interceptor) -> void
110+
def initialize: (Inbound next_interceptor) -> void
111111

112112
def init: (Outbound outbound) -> Outbound
113113

@@ -345,9 +345,9 @@ module Temporalio
345345
end
346346

347347
class Outbound
348-
attr_reader next_interceptor: Outbound?
348+
attr_reader next_interceptor: Outbound
349349

350-
def initialize: (Outbound? next_interceptor) -> void
350+
def initialize: (Outbound next_interceptor) -> void
351351

352352
def cancel_external_workflow: (CancelExternalWorkflowInput input) -> void
353353

temporalio/test/support/sig_applicator.rb

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,35 @@ module SigApplicator
2626
'Temporalio::Workflow::Future'
2727
].freeze
2828

29+
# Specific class#method pairs to skip.
30+
# Internal terminal interceptor implementations pass nil via super(nil)
31+
# to these initializers, but the public API contract is non-nilable.
32+
SKIP_METHODS = Set.new(
33+
[
34+
'Temporalio::Client::Interceptor::Outbound#initialize',
35+
'Temporalio::Worker::Interceptor::Activity::Inbound#initialize',
36+
'Temporalio::Worker::Interceptor::Activity::Outbound#initialize',
37+
'Temporalio::Worker::Interceptor::Workflow::Inbound#initialize',
38+
'Temporalio::Worker::Interceptor::Workflow::Outbound#initialize'
39+
]
40+
).freeze
41+
2942
@type_errors = []
3043
@mutex = Mutex.new
3144

3245
class << self
46+
# Known type mismatches that are not RBI issues. Internal terminal
47+
# interceptor implementations intentionally pass nil as next_interceptor,
48+
# and some tests intentionally pass wrong types to verify error handling.
49+
IGNORED_ERRORS = [
50+
# WorkerActivityTest passes a non-activity class to test validation
51+
# 'WorkerActivityTest::NotAnActivity',
52+
# implementation.rb:231 passes proto WorkflowType object instead of .name
53+
# 'Temporalio::Api::Common::V1::WorkflowType',
54+
# Proto conversion edge case returning inspect string
55+
# 'got type String with value "#<data Temporalio::RetryPo'
56+
].freeze
57+
3358
def apply_all!
3459
configure_error_handler!
3560
register_summary_hook!
@@ -80,6 +105,8 @@ def configure_error_handler!
80105
return
81106
end
82107

108+
return if IGNORED_ERRORS.any? { |pattern| message.include?(pattern) }
109+
83110
SigApplicator.record_type_error(message)
84111
end
85112
end
@@ -159,6 +186,8 @@ def apply_method_sig(target, class_name, method_node, errors, class_method: fals
159186
separator = class_method || method_node.is_singleton ? '.' : '#'
160187
full_name = "#{class_name}#{separator}#{method_name}"
161188

189+
return :skipped if SKIP_METHODS.include?(full_name)
190+
162191
missing_method = false
163192
original = begin
164193
target.instance_method(method_name)
@@ -192,7 +221,7 @@ def apply_method_sig(target, class_name, method_node, errors, class_method: fals
192221
# (e.g., Data.define generates .new, .[], #initialize, #with with a
193222
# single splat) where the RBI provides typed keyword params for better
194223
# static checking but the runtime signature is incompatible.
195-
non_block_params = actual_params.reject { |kind, _| kind == :block }
224+
non_block_params = actual_params.reject { |kind, _| kind == :block } # rubocop:disable Style/HashExcept
196225
all_rest_or_unnamed = non_block_params.all? { |kind, _| kind == :rest || kind == :keyrest }
197226
sig_named_params = method_node.sigs.flat_map { |s| s.params.reject { |p| p.type&.include?('T.proc') } }
198227
return :skipped if all_rest_or_unnamed && non_block_params.any? && sig_named_params.any?

temporalio/test/test.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717

1818
if ENV['TEMPORAL_SORBET_RUNTIME_CHECK']
1919
# Load modules that are lazy-loaded so their types can be instrumented
20-
require 'temporalio/worker/workflow_replayer'
21-
require 'temporalio/converters/payload_codec'
2220
require 'temporalio/contrib/open_telemetry'
21+
require 'temporalio/converters/payload_codec'
2322
require 'temporalio/env_config'
2423
require 'temporalio/simple_plugin'
24+
require 'temporalio/worker/workflow_replayer'
2525

2626
require 'support/sig_applicator'
2727
SigApplicator.apply_all!

0 commit comments

Comments
 (0)