Skip to content

Commit bfdc04d

Browse files
authored
Deprecate use of typing.List (#173)
typing.List is deprecated as of Python 3.9 - use `list`, or `Sequence` or `Iterable` from `collections.abc` instead.
1 parent 4ea8a99 commit bfdc04d

File tree

7 files changed

+39
-51
lines changed

7 files changed

+39
-51
lines changed

src/rpft/parsers/common/rowparser.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,15 @@ def get_list_child_model(model):
4747

4848

4949
def is_list_type(model):
50-
# Determine whether model is a list type,
51-
# such as list, List, List[str], ...
52-
# issubclass only works for Python <=3.6
53-
# model.__dict__.get('__origin__') returns different things in different Python
54-
# version.
55-
# This function tries to accommodate both 3.6 and 3.8 (at least)
50+
"""
51+
Determine whether model is a list type, such as list, list[str], List, List[str].
52+
53+
typing.List is deprecated as of Python 3.9
54+
"""
5655
return (
5756
is_basic_list_type(model)
5857
or model is List
59-
or model.__dict__.get("__origin__") in [list, List]
58+
or getattr(model, "__origin__", None) is list
6059
)
6160

6261

@@ -205,7 +204,7 @@ def assign_value(self, field, key, value, model):
205204
value = list(value)
206205
if isinstance(value[0], str):
207206
assert len(value) == 2
208-
field[key] = {value[0] : value[1]}
207+
field[key] = {value[0]: value[1]}
209208
elif isinstance(value[0], list):
210209
for entry in value:
211210
assert len(entry) == 2
@@ -327,7 +326,11 @@ def parse_entry(
327326
# The model of field[key] is model, and thus value should also be interpreted
328327
# as being of type model.
329328
if not value_is_parsed:
330-
if is_list_type(model) or is_basic_dict_type(model) or is_parser_model_type(model):
329+
if (
330+
is_list_type(model)
331+
or is_basic_dict_type(model)
332+
or is_parser_model_type(model)
333+
):
331334
# If the expected type of the value is list/object,
332335
# parse the cell content as such.
333336
# Otherwise leave it as a string

src/rpft/parsers/creation/contentindexparser.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import importlib
22
import logging
33
from collections import OrderedDict
4-
from typing import Dict, List
5-
64
from rpft.logger.logger import logging_context
75
from rpft.parsers.common.model_inference import model_from_headers
86
from rpft.parsers.common.sheetparser import SheetParser
@@ -58,8 +56,8 @@ def __init__(
5856
self.tag_matcher = tag_matcher
5957
self.template_sheets = {}
6058
self.data_sheets = {}
61-
self.flow_definition_rows: List[ContentIndexRowModel] = []
62-
self.campaign_parsers: Dict[str, tuple[str, CampaignParser]] = {}
59+
self.flow_definition_rows: list[ContentIndexRowModel] = []
60+
self.campaign_parsers: dict[str, tuple[str, CampaignParser]] = {}
6361
self.surveys = {}
6462
self.trigger_parsers = OrderedDict()
6563
self.user_models_module = (

src/rpft/parsers/creation/contentindexrowmodel.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from enum import Enum
2-
from typing import List
32

43
from rpft.parsers.common.rowparser import ParserModel
54
from rpft.parsers.creation.models import SurveyConfig
@@ -24,18 +23,18 @@ class Operation(ParserModel):
2423
class ContentIndexRowModel(ParserModel):
2524
type: str = ""
2625
new_name: str = ""
27-
sheet_name: List[str] = []
26+
sheet_name: list[str] = []
2827
data_sheet: str = ""
2928
data_row_id: str = ""
30-
template_argument_definitions: List[TemplateArgument] = [] # internal name
29+
template_argument_definitions: list[TemplateArgument] = [] # internal name
3130
template_arguments: list = []
3231
options: dict = {}
3332
survey_config: SurveyConfig = SurveyConfig()
3433
operation: Operation = Operation()
3534
data_model: str = ""
3635
group: str = ""
3736
status: str = ""
38-
tags: List[str] = []
37+
tags: list[str] = []
3938

4039
def field_name_to_header_name(field):
4140
if field == "template_argument_definitions":

src/rpft/parsers/creation/flowrowmodel.py

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from typing import List
2-
31
from rpft.parsers.common.rowparser import ParserModel
42
from rpft.parsers.creation.models import Condition
53

@@ -43,7 +41,7 @@ def dict_to_list_of_pairs(headers):
4341
class WhatsAppTemplating(ParserModel):
4442
name: str = ""
4543
uuid: str = ""
46-
variables: List[str] = []
44+
variables: list[str] = []
4745

4846

4947
class Edge(ParserModel):
@@ -69,15 +67,15 @@ def header_name_to_field_name_with_context(header, row):
6967
class FlowRowModel(ParserModel):
7068
row_id: str = ""
7169
type: str
72-
edges: List[Edge]
73-
loop_variable: List[str] = []
70+
edges: list[Edge]
71+
loop_variable: list[str] = []
7472
include_if: bool = True
7573
mainarg_message_text: str = ""
7674
mainarg_value: str = ""
77-
mainarg_groups: List[str] = []
75+
mainarg_groups: list[str] = []
7876
mainarg_none: str = ""
7977
mainarg_dict: list = [] # encoded as list of pairs
80-
mainarg_destination_row_ids: List[str] = []
78+
mainarg_destination_row_ids: list[str] = []
8179
mainarg_flow_name: str = ""
8280
mainarg_expression: str = ""
8381
mainarg_iterlist: list = []
@@ -86,28 +84,22 @@ class FlowRowModel(ParserModel):
8684
data_sheet: str = ""
8785
data_row_id: str = ""
8886
template_arguments: list = []
89-
choices: List[str] = []
87+
choices: list[str] = []
9088
save_name: str = ""
9189
result_category: str = ""
9290
image: str = ""
9391
audio: str = ""
9492
video: str = ""
95-
attachments: List[str] = []
93+
attachments: list[str] = []
9694
urn_scheme: str = ""
9795
obj_name: str = ""
9896
obj_id: str = ""
9997
node_name: str = ""
10098
node_uuid: str = ""
10199
no_response: str = ""
102100
ui_type: str = ""
103-
ui_position: List[str] = []
104-
105-
# TODO: Extra validation here, e.g. from must not be empty
106-
# type must come from row_type_to_main_arg.keys() (see below)
107-
# image/audio/video only makes sense if type == send_message
108-
# mainarg_none should be ''
109-
# _ui_position should be '' or a list of two ints
110-
# ...
101+
ui_position: list[str] = []
102+
111103
def field_name_to_header_name(field):
112104
field_map = {
113105
"node_uuid": "_nodeId",

src/rpft/parsers/creation/models.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from typing import List
2-
31
from rpft.parsers.common.rowparser import ParserModel
42

53

@@ -31,7 +29,7 @@ class ConditionWithMessage(ParserModel):
3129

3230

3331
class ConditionsWithMessage(ParserModel):
34-
conditions: List[ConditionWithMessage] = []
32+
conditions: list[ConditionWithMessage] = []
3533
general_message: str = ""
3634

3735

@@ -61,7 +59,7 @@ class Message(ParserModel):
6159
image: str = ""
6260
audio: str = ""
6361
video: str = ""
64-
attachments: List[str] = []
62+
attachments: list[str] = []
6563

6664

6765
class TemplateSheet:
@@ -76,7 +74,7 @@ def __init__(
7674
self,
7775
flow_definitions,
7876
data_sheets,
79-
templates: List[TemplateSheet],
77+
templates: list[TemplateSheet],
8078
surveys,
8179
):
8280
self.flow_definitions = flow_definitions
@@ -119,7 +117,7 @@ class MCQChoice(ParserModel):
119117

120118

121119
class PostProcessing(ParserModel):
122-
assignments: List[Assignment] = []
120+
assignments: list[Assignment] = []
123121
"""
124122
Assignments to perform via save_value rows.
125123
"""
@@ -157,7 +155,7 @@ class SurveyQuestionModel(ParserModel):
157155
Type of the question.
158156
"""
159157

160-
messages: List[Message]
158+
messages: list[Message]
161159
"""
162160
Question text.
163161
"""
@@ -175,7 +173,7 @@ class SurveyQuestionModel(ParserModel):
175173
the question ID as {variable}_complete.
176174
"""
177175

178-
choices: List[MCQChoice] = []
176+
choices: list[MCQChoice] = []
179177
"""
180178
MCQ specific fields.
181179
"""
@@ -186,7 +184,7 @@ class SurveyQuestionModel(ParserModel):
186184
configuration is used.
187185
"""
188186

189-
relevant: List[Condition] = []
187+
relevant: list[Condition] = []
190188
"""
191189
Conditions required to present the question, otherwise skipped.
192190
"""
@@ -223,7 +221,7 @@ class SurveyQuestionModel(ParserModel):
223221
that is triggered.
224222
"""
225223

226-
tags: List[str] = []
224+
tags: list[str] = []
227225
"""
228226
Tags allowing to filter questions to appear in a survey.
229227
"""

src/rpft/parsers/creation/triggerrowmodel.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
from typing import List
2-
31
from pydantic.v1 import validator
42

53
from rpft.parsers.common.rowparser import ParserModel
64

75

86
class TriggerRowModel(ParserModel):
97
type: str
10-
keywords: List[str] = ""
8+
keywords: list[str] = ""
119
flow: str = ""
12-
groups: List[str] = []
13-
exclude_groups: List[str] = []
10+
groups: list[str] = []
11+
exclude_groups: list[str] = []
1412
channel: str = ""
1513
match_type: str = ""
1614

src/rpft/parsers/sheets.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import json
22
from abc import ABC
3+
from collections.abc import Mapping
34
from pathlib import Path
4-
from typing import List, Mapping
55

66
import tablib
77
from googleapiclient.discovery import build
@@ -28,7 +28,7 @@ def sheets(self) -> Mapping[str, Sheet]:
2828
def get_sheet(self, name) -> Sheet:
2929
return self.sheets.get(name)
3030

31-
def get_sheets_by_name(self, name) -> List[Sheet]:
31+
def get_sheets_by_name(self, name) -> list[Sheet]:
3232
return [sheet] if (sheet := self.get_sheet(name)) else []
3333

3434

0 commit comments

Comments
 (0)