httpx 0.16.1 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/doc/release_notes/0_17_0.md +49 -0
- data/lib/httpx/adapters/webmock.rb +2 -2
- data/lib/httpx/chainable.rb +1 -1
- data/lib/httpx/connection/http1.rb +15 -9
- data/lib/httpx/connection/http2.rb +13 -10
- data/lib/httpx/connection.rb +4 -5
- data/lib/httpx/headers.rb +1 -1
- data/lib/httpx/options.rb +28 -6
- data/lib/httpx/parser/http1.rb +10 -6
- data/lib/httpx/plugins/digest_authentication.rb +4 -4
- data/lib/httpx/plugins/h2c.rb +7 -3
- data/lib/httpx/plugins/multipart/decoder.rb +187 -0
- data/lib/httpx/plugins/multipart/mime_type_detector.rb +3 -3
- data/lib/httpx/plugins/multipart/part.rb +2 -2
- data/lib/httpx/plugins/multipart.rb +14 -0
- data/lib/httpx/plugins/ntlm_authentication.rb +4 -4
- data/lib/httpx/plugins/proxy/ssh.rb +11 -4
- data/lib/httpx/plugins/proxy.rb +6 -4
- data/lib/httpx/plugins/stream.rb +2 -3
- data/lib/httpx/registry.rb +1 -1
- data/lib/httpx/request.rb +6 -7
- data/lib/httpx/resolver/resolver_mixin.rb +2 -1
- data/lib/httpx/response.rb +37 -30
- data/lib/httpx/selector.rb +4 -2
- data/lib/httpx/session.rb +15 -13
- data/lib/httpx/transcoder/form.rb +20 -0
- data/lib/httpx/transcoder/json.rb +12 -0
- data/lib/httpx/transcoder.rb +62 -1
- data/lib/httpx/utils.rb +2 -2
- data/lib/httpx/version.rb +1 -1
- data/sig/buffer.rbs +2 -2
- data/sig/chainable.rbs +6 -1
- data/sig/connection/http1.rbs +10 -4
- data/sig/connection/http2.rbs +16 -5
- data/sig/connection.rbs +4 -4
- data/sig/headers.rbs +19 -18
- data/sig/options.rbs +13 -5
- data/sig/parser/http1.rbs +3 -3
- data/sig/plugins/aws_sigv4.rbs +12 -3
- data/sig/plugins/basic_authentication.rbs +1 -1
- data/sig/plugins/multipart.rbs +64 -8
- data/sig/plugins/proxy.rbs +6 -6
- data/sig/request.rbs +11 -8
- data/sig/resolver/native.rbs +4 -2
- data/sig/resolver/resolver_mixin.rbs +1 -1
- data/sig/resolver/system.rbs +1 -1
- data/sig/response.rbs +8 -2
- data/sig/selector.rbs +8 -6
- data/sig/session.rbs +8 -14
- data/sig/transcoder/form.rbs +1 -0
- data/sig/transcoder/json.rbs +1 -0
- data/sig/transcoder.rbs +5 -4
- metadata +5 -2
data/sig/connection/http2.rbs
CHANGED
@@ -3,10 +3,13 @@ module HTTPX
|
|
3
3
|
include Callbacks
|
4
4
|
include Loggable
|
5
5
|
|
6
|
+
MAX_CONCURRENT_REQUESTS: Integer
|
7
|
+
|
6
8
|
attr_reader streams: Hash[Request, HTTP2Next::Stream]
|
7
9
|
attr_reader pending: Array[Request]
|
8
10
|
|
9
11
|
@options: Options
|
12
|
+
@settings: Hash[Symbol, Integer | bool]
|
10
13
|
@max_concurrent_requests: Integer
|
11
14
|
@max_requests: Integer
|
12
15
|
@drains: Hash[Request, String]
|
@@ -23,7 +26,7 @@ module HTTPX
|
|
23
26
|
|
24
27
|
def <<: (String) -> void
|
25
28
|
|
26
|
-
def can_buffer_more_requests
|
29
|
+
def can_buffer_more_requests?: () -> bool
|
27
30
|
|
28
31
|
def send: (Request) -> void
|
29
32
|
|
@@ -35,7 +38,7 @@ module HTTPX
|
|
35
38
|
|
36
39
|
alias reset init_connection
|
37
40
|
|
38
|
-
def timeout: () ->
|
41
|
+
def timeout: () -> Numeric
|
39
42
|
|
40
43
|
private
|
41
44
|
|
@@ -45,7 +48,7 @@ module HTTPX
|
|
45
48
|
|
46
49
|
def headline_uri: (Request) -> String
|
47
50
|
|
48
|
-
def set_protocol_headers: (Request) -> _Each[[
|
51
|
+
def set_protocol_headers: (Request) -> _Each[[String, String]]
|
49
52
|
|
50
53
|
def handle: (Request request, HTTP2Next::Stream stream) -> void
|
51
54
|
|
@@ -61,9 +64,11 @@ module HTTPX
|
|
61
64
|
|
62
65
|
def on_stream_headers: (HTTP2Next::Stream stream, Request request, Array[[String, String]] headers) -> void
|
63
66
|
|
64
|
-
def on_stream_trailers: (HTTP2Next::Stream stream,
|
67
|
+
def on_stream_trailers: (HTTP2Next::Stream stream, Response response, Array[[String, String]] headers) -> void
|
68
|
+
|
69
|
+
def on_stream_data: (HTTP2Next::Stream stream, Request request, String data) -> void
|
65
70
|
|
66
|
-
def
|
71
|
+
def on_stream_refuse: (HTTP2Next::Stream stream, Request request, StandardError error) -> void
|
67
72
|
|
68
73
|
def on_stream_close: (HTTP2Next::Stream stream, Request request, (Symbol | StandardError)? error) -> void
|
69
74
|
|
@@ -74,12 +79,18 @@ module HTTPX
|
|
74
79
|
def on_close: (Integer last_frame, Symbol? error, String? payload) -> void
|
75
80
|
|
76
81
|
def on_frame_sent: (HTTP2Next::frame) -> void
|
82
|
+
|
77
83
|
def on_frame_received: (HTTP2Next::frame) -> void
|
78
84
|
|
85
|
+
def on_altsvc: (String origin, HTTP2Next::frame) -> void
|
86
|
+
|
79
87
|
def on_promise: (HTTP2Next::Stream) -> void
|
80
88
|
|
81
89
|
def on_origin: (String) -> void
|
82
90
|
|
83
91
|
def on_pong: (string ping) -> void
|
92
|
+
|
93
|
+
class Error < ::HTTPX::Error
|
94
|
+
end
|
84
95
|
end
|
85
96
|
end
|
data/sig/connection.rbs
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module HTTPX
|
2
2
|
class Connection
|
3
|
-
|
4
3
|
interface _Parser
|
5
4
|
|
6
5
|
def on: (Symbol) { (*untyped) -> void } -> void
|
@@ -26,6 +25,7 @@ module HTTPX
|
|
26
25
|
attr_reader state: Symbol
|
27
26
|
attr_reader pending: Array[Request]
|
28
27
|
attr_reader options: Options
|
28
|
+
attr_writer timers: untyped # Timers::Timer
|
29
29
|
|
30
30
|
def addresses: () -> Array[ipaddr]?
|
31
31
|
|
@@ -37,8 +37,7 @@ module HTTPX
|
|
37
37
|
|
38
38
|
def coalescable?: (Connection) -> bool
|
39
39
|
|
40
|
-
def create_idle: (options) -> Connection
|
41
|
-
| () -> Connection
|
40
|
+
def create_idle: (?Hash[Symbol, untyped] options) -> Connection
|
42
41
|
|
43
42
|
def merge: (Connection) -> void
|
44
43
|
|
@@ -47,11 +46,12 @@ module HTTPX
|
|
47
46
|
def match_altsvcs?: (URI::Generic uri) -> bool
|
48
47
|
|
49
48
|
def connecting?: () -> bool
|
49
|
+
|
50
50
|
def inflight?: () -> boolish
|
51
51
|
|
52
52
|
def interests: () -> io_interests?
|
53
53
|
|
54
|
-
def to_io: () ->
|
54
|
+
def to_io: () -> IO
|
55
55
|
|
56
56
|
def call: () -> void
|
57
57
|
|
data/sig/headers.rbs
CHANGED
@@ -2,44 +2,45 @@ module HTTPX
|
|
2
2
|
class Headers
|
3
3
|
include _ToS
|
4
4
|
|
5
|
-
|
5
|
+
EMPTY: Array[untyped]
|
6
6
|
|
7
|
-
|
7
|
+
@headers: Hash[String, Array[String]]
|
8
|
+
|
9
|
+
def self.new: (?untyped headers) -> instance
|
8
10
|
|
9
11
|
def ==: (untyped other) -> bool
|
10
12
|
|
11
|
-
def []: (
|
12
|
-
def []=: (
|
13
|
+
def []: (String field) -> String?
|
14
|
+
def []=: (String field, headers_value value) -> void
|
13
15
|
|
14
|
-
def add: (
|
15
|
-
def delete: (
|
16
|
+
def add: (String field, string value) -> void
|
17
|
+
def delete: (String field) -> Array[String]?
|
16
18
|
|
17
|
-
def each: (?_Each[[
|
18
|
-
| (?_Each[[
|
19
|
+
def each: (?_Each[[String, String]]? extra_headers) { (String k, String v) -> void } -> void
|
20
|
+
| (?_Each[[String, String]]? extra_headers) -> Enumerable[[String, String]]
|
19
21
|
|
20
|
-
def get: (
|
21
|
-
def key?: (
|
22
|
+
def get: (String field) -> Array[String]
|
23
|
+
def key?: (String downcased_key) -> bool
|
22
24
|
|
23
|
-
def merge: (_Each[[
|
25
|
+
def merge: (_Each[[String, headers_value]] other) -> Headers
|
24
26
|
|
25
27
|
def same_headers?: (untyped headers) -> bool
|
26
28
|
|
27
|
-
def to_a: () -> Array[[
|
28
|
-
def to_hash: () -> Hash[
|
29
|
+
def to_a: () -> Array[[String, String]]
|
30
|
+
def to_hash: () -> Hash[String, String]
|
29
31
|
alias to_h to_hash
|
30
32
|
|
31
33
|
def inspect: () -> String
|
32
34
|
|
33
35
|
private
|
34
36
|
|
35
|
-
def initialize: (headers?) -> untyped
|
37
|
+
def initialize: (?headers?) -> untyped
|
36
38
|
def array_value: (headers_value) -> Array[String]
|
37
|
-
def downcased: (
|
39
|
+
def downcased: (_ToS field) -> String
|
38
40
|
end
|
39
41
|
|
40
|
-
type headers_key = String | Symbol
|
41
42
|
type headers_value = _ToS | Array[_ToS]
|
42
|
-
type headers_hash = Hash[
|
43
|
-
type headers_input = headers_hash | Array[[
|
43
|
+
type headers_hash = Hash[_ToS, headers_value]
|
44
|
+
type headers_input = headers_hash | Array[[_ToS, string]]
|
44
45
|
type headers = Headers | headers_input
|
45
46
|
end
|
data/sig/options.rbs
CHANGED
@@ -11,7 +11,7 @@ module HTTPX
|
|
11
11
|
DEFAULT_OPTIONS: Hash[Symbol, untyped]
|
12
12
|
|
13
13
|
type timeout_type = :connect_timeout | :settings_timeout | :operation_timeout | :keep_alive_timeout | :total_timeout
|
14
|
-
type timeout = Hash[timeout_type, Numeric
|
14
|
+
type timeout = Hash[timeout_type, Numeric]
|
15
15
|
|
16
16
|
def self.new: (?options) -> instance
|
17
17
|
|
@@ -26,6 +26,9 @@ module HTTPX
|
|
26
26
|
# timeout
|
27
27
|
attr_reader timeout: timeout
|
28
28
|
|
29
|
+
# http2_settings
|
30
|
+
attr_reader http2_settings: Hash[Symbol, Integer | bool]
|
31
|
+
|
29
32
|
# max_concurrent_requests
|
30
33
|
attr_reader max_concurrent_requests: Integer?
|
31
34
|
|
@@ -45,7 +48,7 @@ module HTTPX
|
|
45
48
|
attr_reader transport_options: Hash[untyped, untyped]?
|
46
49
|
|
47
50
|
# addresses
|
48
|
-
attr_reader addresses:
|
51
|
+
attr_reader addresses: Array[ipaddr]?
|
49
52
|
|
50
53
|
# params
|
51
54
|
attr_reader params: Transcoder::urlencoded_input?
|
@@ -59,6 +62,9 @@ module HTTPX
|
|
59
62
|
# body
|
60
63
|
attr_reader body: bodyIO?
|
61
64
|
|
65
|
+
# body
|
66
|
+
attr_reader origin: URI::Generic?
|
67
|
+
|
62
68
|
# ssl
|
63
69
|
|
64
70
|
# http2_settings
|
@@ -103,13 +109,15 @@ module HTTPX
|
|
103
109
|
attr_reader resolver_options: Hash[Symbol, untyped]?
|
104
110
|
|
105
111
|
def ==: (untyped other) -> bool
|
106
|
-
def merge: (_ToHash[Symbol
|
112
|
+
def merge: (_ToHash[Symbol, untyped] other) -> instance
|
107
113
|
def to_hash: () -> Hash[Symbol, untyped]
|
108
114
|
|
109
115
|
private
|
110
116
|
|
111
|
-
|
117
|
+
REQUEST_IVARS: Array[Symbol]
|
118
|
+
|
119
|
+
def initialize: (?options options) -> untyped
|
112
120
|
end
|
113
121
|
|
114
|
-
type options = Options | Hash[Symbol
|
122
|
+
type options = Options | Hash[Symbol, untyped]
|
115
123
|
end
|
data/sig/parser/http1.rbs
CHANGED
@@ -5,9 +5,9 @@ module HTTPX
|
|
5
5
|
interface _HTTP1Events
|
6
6
|
|
7
7
|
def on_start: () -> void
|
8
|
-
def on_headers: (parsed_headers) -> void
|
9
|
-
def on_trailers: (parsed_headers) -> void
|
10
|
-
def on_data: (String) -> void
|
8
|
+
def on_headers: (parsed_headers headers) -> void
|
9
|
+
def on_trailers: (parsed_headers trailers) -> void
|
10
|
+
def on_data: (String data) -> void
|
11
11
|
def on_complete: () -> void
|
12
12
|
end
|
13
13
|
|
data/sig/plugins/aws_sigv4.rbs
CHANGED
@@ -9,13 +9,21 @@ module HTTPX
|
|
9
9
|
|
10
10
|
module AWSSigV4
|
11
11
|
|
12
|
-
Credentials
|
12
|
+
class Credentials < Struct[[String, String, String?]]
|
13
|
+
attr_reader username: String
|
14
|
+
attr_reader password: String
|
15
|
+
attr_reader security_token: String?
|
16
|
+
end
|
13
17
|
|
14
18
|
|
15
19
|
class Signer
|
16
20
|
|
17
|
-
|
21
|
+
@unsigned_headers: Set[String]
|
22
|
+
|
23
|
+
def sign!: (Request & RequestMethods request) -> void
|
18
24
|
|
25
|
+
def self.new: (instance) -> instance
|
26
|
+
| (**untyped params) -> instance
|
19
27
|
private
|
20
28
|
|
21
29
|
def initialize: (
|
@@ -33,9 +41,10 @@ module HTTPX
|
|
33
41
|
) -> untyped
|
34
42
|
|
35
43
|
|
36
|
-
def
|
44
|
+
def hexdigest: (bodyIO value) -> String
|
37
45
|
|
38
46
|
def hmac: (String key, String value) -> String
|
47
|
+
|
39
48
|
def hexhmac: (String key, String value) -> String
|
40
49
|
end
|
41
50
|
|
@@ -10,6 +10,6 @@ module HTTPX
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
type sessionBasicAuthentication = sessionAuthentication & BasicAuthentication::InstanceMethods
|
13
|
+
type sessionBasicAuthentication = sessionAuthentication & Authentication::InstanceMethods & BasicAuthentication::InstanceMethods
|
14
14
|
end
|
15
15
|
end
|
data/sig/plugins/multipart.rbs
CHANGED
@@ -1,41 +1,97 @@
|
|
1
1
|
module HTTPX
|
2
2
|
module Plugins
|
3
3
|
module Multipart
|
4
|
+
interface _MultipartInput
|
5
|
+
def filename: () -> String
|
6
|
+
def content_type: () -> String
|
7
|
+
def read: (?int? length, ?string? output) -> String?
|
8
|
+
end
|
9
|
+
|
10
|
+
MULTIPART_VALUE_COND: ^(_Reader | record_multipart_value value) -> bool
|
11
|
+
|
4
12
|
def self.load_dependencies: (singleton(Session)) -> void
|
5
13
|
def self.configure: (*untyped) -> void
|
6
14
|
def self?.encode: (untyped) -> (Encoder | Transcoder::Form::Encoder)
|
15
|
+
def self?.decode: (HTTPX::Response response) -> Transcoder::_Decoder
|
16
|
+
|
17
|
+
def self?.normalize_keys: [U] (_ToS key, _ToAry[untyped] | _ToHash[_ToS, untyped] | untyped value) { (String, ?untyped) -> U } -> U
|
7
18
|
|
8
19
|
type multipart_value = string | Pathname | File | _Reader
|
9
20
|
|
10
|
-
type record_multipart_value = multipart_value |
|
11
|
-
{ content_type: String, filename: String, body: multipart_value } |
|
21
|
+
type record_multipart_value = { content_type: String, filename: String, body: multipart_value } |
|
12
22
|
{ content_type: String, body: multipart_value }
|
13
23
|
|
14
24
|
type multipart_nested_value = multipart_value | _ToAry[multipart_value] | _ToHash[string, multipart_value]
|
15
25
|
|
16
26
|
class Encoder
|
17
27
|
include Transcoder::_Encoder
|
18
|
-
|
28
|
+
|
29
|
+
@boundary: String
|
30
|
+
@part_index: Integer
|
31
|
+
@buffer: String
|
32
|
+
|
33
|
+
@form: Enumerable[[Symbol | string, multipart_nested_value]]
|
34
|
+
@parts: Array[_Reader]
|
19
35
|
|
20
36
|
def content_type: () -> String
|
21
37
|
|
38
|
+
def read: (?int? length, ?string? buffer) -> String?
|
39
|
+
|
40
|
+
def rewind: () -> void
|
41
|
+
|
22
42
|
private
|
23
43
|
|
24
|
-
def
|
44
|
+
def to_parts: (Enumerable[[Symbol | string, multipart_nested_value]] multipart_data) -> Array[_Reader]
|
45
|
+
|
46
|
+
def initialize: (Enumerable[[Symbol | string, multipart_nested_value]] multipart_data) -> untyped
|
25
47
|
|
26
48
|
def header_part: (string key, String content_type, String? filename) -> StringIO
|
27
49
|
|
28
|
-
def read_chunks: (String buffer, Integer? length) -> void
|
50
|
+
def read_chunks: (String buffer, ?Integer? length) -> void
|
29
51
|
|
30
|
-
def read_from_part: (Integer? max_length) ->
|
52
|
+
def read_from_part: (?Integer? max_length) -> String?
|
53
|
+
end
|
54
|
+
|
55
|
+
class Decoder
|
56
|
+
BOUNDARY_RE: Regexp
|
57
|
+
|
58
|
+
@state: :idle | :part_header | :part_body | :parse_boundary | :done
|
59
|
+
@buffer: String
|
60
|
+
@parts: Hash[String, untyped]
|
61
|
+
@boundary: String
|
62
|
+
@intermediate_boundary: String
|
63
|
+
|
64
|
+
def call: (Response response, untyped) -> Hash[String, untyped]
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def initialize: (Response response) -> void
|
69
|
+
|
70
|
+
def parse: () -> void
|
71
|
+
|
72
|
+
def get_filename: (String head) -> String?
|
73
|
+
end
|
74
|
+
|
75
|
+
class FilePart # < SimpleDelegator
|
76
|
+
attr_reader original_filename: String
|
77
|
+
attr_reader content_type: String
|
78
|
+
|
79
|
+
# @file: Tempfile
|
80
|
+
|
81
|
+
# private
|
82
|
+
|
83
|
+
def initialize: (String filename, String content_type) -> void
|
31
84
|
end
|
32
85
|
|
33
86
|
module Part
|
34
|
-
def self?.call: (
|
87
|
+
def self?.call: [U] (_MultipartInput multipart_input) -> [U, String, String]
|
88
|
+
| (multipart_nested_value input) -> ([StringIO, String, String?] | [File, String, String])
|
35
89
|
end
|
36
90
|
|
37
91
|
module MimeTypeDetector
|
38
|
-
|
92
|
+
DEFAULT_MIMETYPE: String
|
93
|
+
|
94
|
+
def self?.call: (::IO file, String filename) -> String?
|
39
95
|
end
|
40
96
|
end
|
41
97
|
end
|
data/sig/plugins/proxy.rbs
CHANGED
@@ -9,8 +9,8 @@ module HTTPX
|
|
9
9
|
|
10
10
|
class Parameters
|
11
11
|
attr_reader uri: URI::Generic
|
12
|
-
attr_reader username:
|
13
|
-
attr_reader password:
|
12
|
+
attr_reader username: String?
|
13
|
+
attr_reader password: String?
|
14
14
|
|
15
15
|
def authenticated?: () -> boolish
|
16
16
|
def token_authentication: () -> String?
|
@@ -19,7 +19,7 @@ module HTTPX
|
|
19
19
|
|
20
20
|
private
|
21
21
|
|
22
|
-
def initialize: (uri: generic_uri, ?username:
|
22
|
+
def initialize: (uri: generic_uri, ?username: String, ?password: String) -> untyped
|
23
23
|
end
|
24
24
|
|
25
25
|
def self.configure: (singleton(Session)) -> void
|
@@ -35,9 +35,9 @@ module HTTPX
|
|
35
35
|
module InstanceMethods
|
36
36
|
private
|
37
37
|
|
38
|
-
def proxy_uris: (
|
39
|
-
| (
|
40
|
-
| (
|
38
|
+
def proxy_uris: (generic_uri, Options & _ProxyOptions) -> { uri: generic_uri, username: String, password: String }
|
39
|
+
| (generic_uri, Options & _ProxyOptions) -> { uri: generic_uri }
|
40
|
+
| (generic_uri, Options & _ProxyOptions) -> nil
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
data/sig/request.rbs
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
module HTTPX
|
2
2
|
class Request
|
3
|
+
extend Forwardable
|
3
4
|
include Callbacks
|
4
5
|
|
5
|
-
METHODS: Array[
|
6
|
+
METHODS: Array[Symbol]
|
6
7
|
USER_AGENT: String
|
7
8
|
|
8
|
-
attr_reader verb:
|
9
|
-
attr_reader uri: URI::
|
9
|
+
attr_reader verb: Symbol
|
10
|
+
attr_reader uri: URI::Generic
|
10
11
|
attr_reader headers: Headers
|
11
12
|
attr_reader body: Body
|
12
13
|
attr_reader state: Symbol
|
@@ -14,13 +15,13 @@ module HTTPX
|
|
14
15
|
attr_reader response: response?
|
15
16
|
attr_reader drain_error: StandardError?
|
16
17
|
|
17
|
-
def initialize: (
|
18
|
+
def initialize: (Symbol | String, generic_uri, ?options) -> untyped
|
18
19
|
|
19
20
|
def interests: () -> (:r | :w)
|
20
21
|
|
21
|
-
def merge_headers: (_Each[[
|
22
|
+
def merge_headers: (_Each[[String, headers_value]]) -> void
|
22
23
|
|
23
|
-
def scheme: () ->
|
24
|
+
def scheme: () -> String
|
24
25
|
|
25
26
|
def response=: (response) -> void
|
26
27
|
|
@@ -49,6 +50,7 @@ module HTTPX
|
|
49
50
|
def each: () { (String) -> void } -> void
|
50
51
|
| () -> Enumerable[String]
|
51
52
|
|
53
|
+
def rewind: () -> void
|
52
54
|
def empty?: () -> bool
|
53
55
|
def bytesize: () -> Numeric
|
54
56
|
def stream: (Transcoder::_Encoder) -> bodyIO
|
@@ -59,8 +61,9 @@ module HTTPX
|
|
59
61
|
end
|
60
62
|
|
61
63
|
class ProcIO
|
62
|
-
|
63
|
-
|
64
|
+
def initialize: (^(String) -> void) -> untyped
|
65
|
+
|
66
|
+
def write: (String data) -> Integer
|
64
67
|
end
|
65
68
|
end
|
66
69
|
end
|