1
1
import linecache
2
2
import textwrap
3
+ from dataclasses import dataclass , field
3
4
from typing import Any , Dict , List , Optional
4
5
5
- import attr
6
6
from gherkin .errors import CompositeParserException
7
7
from gherkin .parser import Parser
8
8
from gherkin .token_scanner import TokenScanner
11
11
from .types import STEP_TYPES
12
12
13
13
14
- @attr . s
14
+ @dataclass
15
15
class Location :
16
- column = attr . ib ( type = int )
17
- line = attr . ib ( type = int )
16
+ column : int
17
+ line : int
18
18
19
19
@classmethod
20
20
def from_dict (cls , data : Dict [str , Any ]) -> "Location" :
21
21
return cls (column = data ["column" ], line = data ["line" ])
22
22
23
23
24
- @attr . s
24
+ @dataclass
25
25
class Comment :
26
- location = attr . ib ( type = Location )
27
- text = attr . ib ( type = str )
26
+ location : Location
27
+ text : str
28
28
29
29
@classmethod
30
30
def from_dict (cls , data : Dict [str , Any ]) -> "Comment" :
31
31
return cls (location = Location .from_dict (data ["location" ]), text = data ["text" ])
32
32
33
33
34
- @attr . s
34
+ @dataclass
35
35
class Cell :
36
- location = attr . ib ( type = Location )
37
- value = attr . ib ( type = str )
36
+ location : Location
37
+ value : str
38
38
39
39
@classmethod
40
40
def from_dict (cls , data : Dict [str , Any ]) -> "Cell" :
41
41
return cls (location = Location .from_dict (data ["location" ]), value = _convert_to_raw_string (data ["value" ]))
42
42
43
43
44
- @attr . s
44
+ @dataclass
45
45
class Row :
46
- id = attr . ib ( type = str )
47
- location = attr . ib ( type = Location )
48
- cells = attr . ib ( type = List [Cell ])
46
+ id : str
47
+ location : Location
48
+ cells : List [Cell ]
49
49
50
50
@classmethod
51
51
def from_dict (cls , data : Dict [str , Any ]) -> "Row" :
@@ -56,12 +56,12 @@ def from_dict(cls, data: Dict[str, Any]) -> "Row":
56
56
)
57
57
58
58
59
- @attr . s
59
+ @dataclass
60
60
class DataTable :
61
- location = attr . ib ( type = Location )
62
- name = attr . ib ( type = Optional [str ], default = None )
63
- tableHeader = attr . ib ( type = Optional [Row ], default = None )
64
- tableBody = attr . ib ( type = Optional [List [Row ]], factory = list )
61
+ location : Location
62
+ name : Optional [str ] = None
63
+ tableHeader : Optional [Row ] = None
64
+ tableBody : Optional [List [Row ]] = field ( default_factory = list )
65
65
66
66
@classmethod
67
67
def from_dict (cls , data : Dict [str , Any ]) -> "DataTable" :
@@ -73,31 +73,31 @@ def from_dict(cls, data: Dict[str, Any]) -> "DataTable":
73
73
)
74
74
75
75
76
- @attr . s
76
+ @dataclass
77
77
class DocString :
78
- content = attr . ib ( type = str )
79
- delimiter = attr . ib ( type = str )
80
- location = attr . ib ( type = Location )
78
+ content : str
79
+ delimiter : str
80
+ location : Location
81
81
82
- def __attrs_post_init__ (self ):
82
+ def __post_init__ (self ):
83
83
self .content = textwrap .dedent (self .content )
84
84
85
85
@classmethod
86
86
def from_dict (cls , data : Dict [str , Any ]) -> "DocString" :
87
87
return cls (content = data ["content" ], delimiter = data ["delimiter" ], location = Location .from_dict (data ["location" ]))
88
88
89
89
90
- @attr . s
90
+ @dataclass
91
91
class Step :
92
- id = attr . ib ( type = str )
93
- keyword = attr . ib ( type = str )
94
- keywordType = attr . ib ( type = str )
95
- location = attr . ib ( type = Location )
96
- text = attr . ib ( type = str )
97
- dataTable = attr . ib ( type = Optional [DataTable ], default = None )
98
- docString = attr . ib ( type = Optional [DocString ], default = None )
99
-
100
- def __attrs_post_init__ (self ):
92
+ id : str
93
+ keyword : str
94
+ keywordType : str
95
+ location : Location
96
+ text : str
97
+ dataTable : Optional [DataTable ] = None
98
+ docString : Optional [DocString ] = None
99
+
100
+ def __post_init__ (self ):
101
101
self .keyword = self .keyword .lower ().strip ()
102
102
103
103
@property
@@ -121,29 +121,29 @@ def from_dict(cls, data: Dict[str, Any]) -> "Step":
121
121
)
122
122
123
123
124
- @attr . s
124
+ @dataclass
125
125
class Tag :
126
- id = attr . ib ( type = str )
127
- location = attr . ib ( type = Location )
128
- name = attr . ib ( type = str )
126
+ id : str
127
+ location : Location
128
+ name : str
129
129
130
130
@classmethod
131
131
def from_dict (cls , data : Dict [str , Any ]) -> "Tag" :
132
132
return cls (id = data ["id" ], location = Location .from_dict (data ["location" ]), name = data ["name" ])
133
133
134
134
135
- @attr . s
135
+ @dataclass
136
136
class Scenario :
137
- id = attr . ib ( type = str )
138
- keyword = attr . ib ( type = str )
139
- location = attr . ib ( type = Location )
140
- name = attr . ib ( type = str )
141
- description = attr . ib ( type = str )
142
- steps = attr . ib ( type = List [Step ])
143
- tags = attr . ib ( type = List [Tag ])
144
- examples = attr . ib ( type = Optional [List [DataTable ]], factory = list )
145
-
146
- def __attrs_post_init__ (self ):
137
+ id : str
138
+ keyword : str
139
+ location : Location
140
+ name : str
141
+ description : str
142
+ steps : List [Step ]
143
+ tags : List [Tag ]
144
+ examples : Optional [List [DataTable ]] = field ( default_factory = list )
145
+
146
+ def __post_init__ (self ):
147
147
self .steps = _compute_given_when_then (self .steps )
148
148
149
149
@classmethod
@@ -160,15 +160,15 @@ def from_dict(cls, data: Dict[str, Any]) -> "Scenario":
160
160
)
161
161
162
162
163
- @attr . s
163
+ @dataclass
164
164
class Rule :
165
- id = attr . ib ( type = str )
166
- keyword = attr . ib ( type = str )
167
- location = attr . ib ( type = Location )
168
- name = attr . ib ( type = str )
169
- description = attr . ib ( type = str )
170
- tags = attr . ib ( type = List [Tag ])
171
- children = attr . ib ( type = List [Scenario ])
165
+ id : str
166
+ keyword : str
167
+ location : Location
168
+ name : str
169
+ description : str
170
+ tags : List [Tag ]
171
+ children : List [Scenario ]
172
172
173
173
@classmethod
174
174
def from_dict (cls , data : Dict [str , Any ]) -> "Rule" :
@@ -183,16 +183,16 @@ def from_dict(cls, data: Dict[str, Any]) -> "Rule":
183
183
)
184
184
185
185
186
- @attr . s
186
+ @dataclass
187
187
class Background :
188
- id = attr . ib ( type = str )
189
- keyword = attr . ib ( type = str )
190
- location = attr . ib ( type = Location )
191
- name = attr . ib ( type = str )
192
- description = attr . ib ( type = str )
193
- steps = attr . ib ( type = List [Step ])
194
-
195
- def __attrs_post_init__ (self ):
188
+ id : str
189
+ keyword : str
190
+ location : Location
191
+ name : str
192
+ description : str
193
+ steps : List [Step ]
194
+
195
+ def __post_init__ (self ):
196
196
self .steps = _compute_given_when_then (self .steps )
197
197
198
198
@classmethod
@@ -207,11 +207,11 @@ def from_dict(cls, data: Dict[str, Any]) -> "Background":
207
207
)
208
208
209
209
210
- @attr . s
210
+ @dataclass
211
211
class Child :
212
- background = attr . ib ( type = Optional [Background ], default = None )
213
- rule = attr . ib ( type = Optional [Rule ], default = None )
214
- scenario = attr . ib ( type = Optional [Scenario ], default = None )
212
+ background : Optional [Background ] = None
213
+ rule : Optional [Rule ] = None
214
+ scenario : Optional [Scenario ] = None
215
215
216
216
@classmethod
217
217
def from_dict (cls , data : Dict [str , Any ]) -> "Child" :
@@ -222,14 +222,14 @@ def from_dict(cls, data: Dict[str, Any]) -> "Child":
222
222
)
223
223
224
224
225
- @attr . s
225
+ @dataclass
226
226
class Feature :
227
- keyword = attr . ib ( type = str )
228
- location = attr . ib ( type = Location )
229
- tags = attr . ib ( type = List [Tag ])
230
- name = attr . ib ( type = str )
231
- description = attr . ib ( type = str )
232
- children = attr . ib ( type = List [Child ])
227
+ keyword : str
228
+ location : Location
229
+ tags : List [Tag ]
230
+ name : str
231
+ description : str
232
+ children : List [Child ]
233
233
234
234
@classmethod
235
235
def from_dict (cls , data : Dict [str , Any ]) -> "Feature" :
@@ -243,10 +243,10 @@ def from_dict(cls, data: Dict[str, Any]) -> "Feature":
243
243
)
244
244
245
245
246
- @attr . s
246
+ @dataclass
247
247
class GherkinDocument :
248
- feature = attr . ib ( type = Feature )
249
- comments = attr . ib ( type = List [Comment ])
248
+ feature : Feature
249
+ comments : List [Comment ]
250
250
251
251
@classmethod
252
252
def from_dict (cls , data : Dict [str , Any ]) -> "GherkinDocument" :
@@ -283,5 +283,4 @@ def get_gherkin_document(abs_filename: str = None, encoding: str = "utf-8") -> G
283
283
abs_filename ,
284
284
) from e
285
285
286
- # Assuming gherkin_data is a dictionary with the structure expected by from_dict methods
287
286
return GherkinDocument .from_dict (gherkin_data )
0 commit comments