Skip to content

Commit 3178ddc

Browse files
Use python 3.10 syntax (#53)
1 parent a86e915 commit 3178ddc

33 files changed

+121
-152
lines changed

common/common/abstract_charm.py

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
"""MySQL Router charm"""
55

66
import abc
7+
import collections.abc
78
import dataclasses
89
import logging
9-
import typing
1010

1111
import charm_refresh
1212
import ops
@@ -99,7 +99,7 @@ def __init__(self, *args) -> None:
9999

100100
@property
101101
@abc.abstractmethod
102-
def _subordinate_relation_endpoint_names(self) -> typing.Optional[typing.Iterable[str]]:
102+
def _subordinate_relation_endpoint_names(self) -> collections.abc.Collection[str] | None:
103103
"""Subordinate relation endpoint names
104104
105105
Does NOT include relations where charm is principal
@@ -117,7 +117,7 @@ def _logrotate(self) -> logrotate.LogRotate:
117117

118118
@property
119119
@abc.abstractmethod
120-
def _cos_relation_type(self) -> typing.Type[cos.COSRelation]:
120+
def _cos_relation_type(self) -> type[cos.COSRelation]:
121121
"""COSRelation type"""
122122

123123
@abc.abstractmethod
@@ -129,22 +129,22 @@ def _read_only_endpoints(self, *, event) -> str:
129129
"""MySQL Router read-only endpoint"""
130130

131131
@abc.abstractmethod
132-
def is_externally_accessible(self, *, event) -> typing.Optional[bool]:
132+
def is_externally_accessible(self, *, event) -> bool | None:
133133
"""Whether endpoints should be externally accessible.
134134
135135
Only defined in vm charm to return True/False. In k8s charm, returns None.
136136
"""
137137

138138
@abc.abstractmethod
139-
def tls_sans_ip(self, *, event) -> typing.Optional[typing.List[str]]:
139+
def tls_sans_ip(self, *, event) -> list[str] | None:
140140
"""TLS IP subject alternative names"""
141141

142142
@abc.abstractmethod
143-
def tls_sans_dns(self, *, event) -> typing.Optional[typing.List[str]]:
143+
def tls_sans_dns(self, *, event) -> list[str] | None:
144144
"""TLS DNS subject alternative names"""
145145

146146
@abc.abstractmethod
147-
def _status(self, *, event) -> typing.Optional[ops.StatusBase]:
147+
def _status(self, *, event) -> ops.StatusBase | None:
148148
"""Status of the charm."""
149149

150150
@property
@@ -153,26 +153,26 @@ def _tls_certificate_saved(self) -> bool:
153153
return self.tls.certificate_saved
154154

155155
@property
156-
def _tls_key(self) -> typing.Optional[str]:
156+
def _tls_key(self) -> str | None:
157157
"""Custom TLS key"""
158158
return self.tls.key
159159

160160
@property
161-
def _tls_certificate_authority(self) -> typing.Optional[str]:
161+
def _tls_certificate_authority(self) -> str | None:
162162
"""Custom TLS certificate authority"""
163163
return self.tls.certificate_authority
164164

165165
@property
166-
def _tls_certificate(self) -> typing.Optional[str]:
166+
def _tls_certificate(self) -> str | None:
167167
"""Custom TLS certificate"""
168168
return self.tls.certificate
169169

170170
@property
171-
def tracing_endpoint(self) -> typing.Optional[str]:
171+
def tracing_endpoint(self) -> str | None:
172172
"""Otlp http endpoint for charm instrumentation."""
173173
return self._cos_relation.tracing_endpoint
174174

175-
def _cos_exporter_config(self, event) -> typing.Optional[cos.ExporterConfig]:
175+
def _cos_exporter_config(self, event) -> cos.ExporterConfig | None:
176176
"""Returns the exporter config for MySQLRouter exporter if cos relation exists"""
177177
cos_relation_exists = (
178178
self._cos_relation.relation_exists
@@ -203,8 +203,7 @@ def get_workload(self, *, event, refresh: charm_refresh.Common = None):
203203
)
204204

205205
@staticmethod
206-
# TODO python3.10 min version: Use `list` instead of `typing.List`
207-
def _prioritize_statuses(statuses: typing.List[ops.StatusBase]) -> ops.StatusBase:
206+
def _prioritize_statuses(statuses: list[ops.StatusBase]) -> ops.StatusBase:
208207
"""Report the highest priority status.
209208
210209
(Statuses of the same type are reported in the order they were added to `statuses`)

common/common/container.py

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,7 @@ def rmtree(self):
5555
class CalledProcessError(subprocess.CalledProcessError):
5656
"""Command returned non-zero exit code"""
5757

58-
# TODO python3.10 min version: Use `list` instead of `typing.List`
59-
def __init__(
60-
self, *, returncode: int, cmd: typing.List[str], output: str, stderr: str
61-
) -> None:
58+
def __init__(self, *, returncode: int, cmd: list[str], output: str, stderr: str) -> None:
6259
super().__init__(returncode=returncode, cmd=cmd, output=output, stderr=stderr)
6360

6461

@@ -201,12 +198,11 @@ def refresh(
201198
"""
202199

203200
@abc.abstractmethod
204-
# TODO python3.10 min version: Use `list` instead of `typing.List`
205201
def _run_command(
206202
self,
207-
command: typing.List[str],
203+
command: list[str],
208204
*,
209-
timeout: typing.Optional[int],
205+
timeout: int | None,
210206
input: str = None, # noqa: A002 Match subprocess.run()
211207
) -> str:
212208
"""Run command in container.
@@ -215,8 +211,7 @@ def _run_command(
215211
CalledProcessError: Command returns non-zero exit code
216212
"""
217213

218-
# TODO python3.10 min version: Use `list` instead of `typing.List`
219-
def run_mysql_router(self, args: typing.List[str], *, timeout: int = None) -> str:
214+
def run_mysql_router(self, args: list[str], *, timeout: int = None) -> str:
220215
"""Run MySQL Router command.
221216
222217
Raises:
@@ -225,10 +220,9 @@ def run_mysql_router(self, args: typing.List[str], *, timeout: int = None) -> st
225220
args.insert(0, self._mysql_router_command)
226221
return self._run_command(args, timeout=timeout)
227222

228-
# TODO python3.10 min version: Use `list` instead of `typing.List`
229223
def run_mysql_shell(
230224
self,
231-
args: typing.List[str],
225+
args: list[str],
232226
*,
233227
timeout: int = None,
234228
input: str = None, # noqa: A002 Match subprocess.run()
@@ -251,9 +245,7 @@ def create_router_rest_api_credentials_file(self) -> None:
251245
# create empty credentials file
252246
self.rest_api_credentials_file.write_text("")
253247

254-
def set_mysql_router_rest_api_password(
255-
self, *, user: str, password: typing.Optional[str]
256-
) -> None:
248+
def set_mysql_router_rest_api_password(self, *, user: str, password: str | None) -> None:
257249
"""Set REST API credentials using the mysqlrouter_password command."""
258250
self.create_router_rest_api_credentials_file()
259251

common/common/lifecycle.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
https://juju.is/docs/sdk/a-charms-life
77
"""
88

9+
import collections.abc
910
import enum
1011
import logging
11-
import typing
1212

1313
import ops
1414

@@ -37,7 +37,7 @@ class Unit(ops.Object):
3737
def __init__(
3838
self,
3939
charm: ops.CharmBase,
40-
subordinated_relation_endpoint_names: typing.Optional[typing.Iterable[str]],
40+
subordinated_relation_endpoint_names: collections.abc.Collection[str] | None,
4141
):
4242
"""Unit lifecycle
4343

common/common/mysql_shell/__init__.py

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@
2626
logger = logging.getLogger(__name__)
2727

2828

29-
# TODO python3.10 min version: Add `(kw_only=True)`
30-
@dataclasses.dataclass
29+
@dataclasses.dataclass(kw_only=True)
3130
class RouterUserInformation:
3231
"""MySQL Router user information"""
3332

@@ -49,8 +48,7 @@ def __init__(self, *, message: str, code: int, traceback_message: str):
4948
self.traceback_message = traceback_message
5049

5150

52-
# TODO python3.10 min version: Add `(kw_only=True)`
53-
@dataclasses.dataclass
51+
@dataclasses.dataclass(kw_only=True)
5452
class Shell:
5553
"""MySQL Shell connected to MySQL cluster"""
5654

@@ -109,8 +107,7 @@ def _run_code(self, code: str) -> None:
109107
)
110108
raise
111109

112-
# TODO python3.10 min version: Use `list` instead of `typing.List`
113-
def _run_sql(self, sql_statements: typing.List[str]) -> None:
110+
def _run_sql(self, sql_statements: list[str]) -> None:
114111
"""Connect to MySQL cluster and execute SQL."""
115112
self._run_code(
116113
_jinja_env.get_template("run_sql.py.jinja").render(statements=sql_statements)
@@ -127,10 +124,9 @@ def _get_attributes(self, additional_attributes: dict = None) -> str:
127124
attributes.update(additional_attributes)
128125
return json.dumps(attributes)
129126

130-
# TODO python3.10 min version: Use `set` instead of `typing.Set`
131-
def _get_mysql_databases(self) -> typing.Set[str]:
127+
def _get_mysql_databases(self) -> set[str]:
132128
"""Returns a set with the MySQL databases."""
133-
logger.debug(f"Getting MySQL databases")
129+
logger.debug("Getting MySQL databases")
134130
output_file = self._container.path("/tmp/mysqlsh_output.json")
135131
self._run_code(
136132
_jinja_env.get_template("get_mysql_databases.py.jinja").render(
@@ -143,8 +139,7 @@ def _get_mysql_databases(self) -> typing.Set[str]:
143139
logger.debug(f"MySQL databases found: {len(rows)}")
144140
return {row[0] for row in rows}
145141

146-
# TODO python3.10 min version: Use `set` instead of `typing.Set`
147-
def _get_mysql_roles(self, name_pattern: str) -> typing.Set[str]:
142+
def _get_mysql_roles(self, name_pattern: str) -> set[str]:
148143
"""Returns a set with the MySQL roles."""
149144
logger.debug(f"Getting MySQL roles with {name_pattern=}")
150145
output_file = self._container.path("/tmp/mysqlsh_output.json")
@@ -231,9 +226,7 @@ def add_attributes_to_mysql_router_user(
231226
self._run_sql([f"ALTER USER `{username}` ATTRIBUTE '{attributes}'"])
232227
logger.debug(f"Added {attributes=} to {username=}")
233228

234-
def get_mysql_router_user_for_unit(
235-
self, unit_name: str
236-
) -> typing.Optional[RouterUserInformation]:
229+
def get_mysql_router_user_for_unit(self, unit_name: str) -> RouterUserInformation | None:
237230
"""Get MySQL Router user created by a previous instance of the unit.
238231
239232
Get username & router ID attribute.

common/common/relations/cos.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def relation_exists(self) -> bool:
7171

7272
@property
7373
@abc.abstractmethod
74-
def tracing_endpoint(self) -> typing.Optional[str]:
74+
def tracing_endpoint(self) -> str | None:
7575
"""The tracing endpoint."""
7676

7777
def get_monitoring_password(self) -> str:

common/common/relations/database_provides.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,7 @@ def __init__(self, charm_: "abstract_charm.MySQLRouterCharm") -> None:
191191
charm_.framework.observe(self._interface.on.database_requested, charm_.reconcile)
192192

193193
@property
194-
# TODO python3.10 min version: Use `list` instead of `typing.List`
195-
def _shared_users(self) -> typing.List[_RelationWithSharedUser]:
194+
def _shared_users(self) -> list[_RelationWithSharedUser]:
196195
shared_users = []
197196
for relation in self._interface.relations:
198197
try:
@@ -297,15 +296,14 @@ def delete_all_databags(self) -> None:
297296
relation.delete_databag()
298297
logger.debug("Deleted all application databags")
299298

300-
def get_status(self, event) -> typing.Optional[ops.StatusBase]:
299+
def get_status(self, event) -> ops.StatusBase | None:
301300
"""Report non-active status."""
302301
requested_users = []
303302
exception_reporting_priority = (
304303
_UnsupportedExtraUserRole,
305304
remote_databag.IncompleteDatabag,
306305
)
307-
# TODO python3.10 min version: Use `list` instead of `typing.List`
308-
exceptions: typing.List[status_exception.StatusException] = []
306+
exceptions: list[status_exception.StatusException] = []
309307
for relation in self._interface.relations:
310308
try:
311309
requested_users.append(

common/common/relations/database_requires.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def __init__(self, charm_: "abstract_charm.MySQLRouterCharm") -> None:
113113
charm_.framework.observe(self._interface.on.database_created, charm_.reconcile)
114114
charm_.framework.observe(self._interface.on.endpoints_changed, charm_.reconcile)
115115

116-
def get_connection_info(self, *, event) -> typing.Optional[CompleteConnectionInformation]:
116+
def get_connection_info(self, *, event) -> CompleteConnectionInformation | None:
117117
"""Information for connection to MySQL cluster"""
118118
try:
119119
return CompleteConnectionInformation(interface=self._interface, event=event)
@@ -130,7 +130,7 @@ def is_relation_breaking(self, event) -> bool:
130130
pass
131131
return False
132132

133-
def get_status(self, event) -> typing.Optional[ops.StatusBase]:
133+
def get_status(self, event) -> ops.StatusBase | None:
134134
"""Report non-active status."""
135135
try:
136136
CompleteConnectionInformation(interface=self._interface, event=event)

common/common/relations/remote_databag.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
"""Relation databag for remote application"""
55

66
import logging
7-
import typing
87

98
import ops
109

@@ -28,10 +27,7 @@ class RemoteDatabag(dict):
2827

2928
def __init__(
3029
self,
31-
# TODO python3.10 min version: Use `|` instead of `typing.Union`
32-
interface: typing.Union[
33-
data_interfaces.DatabaseRequires, data_interfaces.DatabaseProvides
34-
],
30+
interface: data_interfaces.DatabaseRequires | data_interfaces.DatabaseProvides,
3531
relation: ops.Relation,
3632
) -> None:
3733
super().__init__(interface.fetch_relation_data()[relation.id])

common/common/relations/secrets.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ def __init__(
2828
self,
2929
charm: "abstract_charm.MySQLRouterCharm",
3030
relation_name: str,
31-
app_secret_fields: typing.List[str] = [],
32-
unit_secret_fields: typing.List[str] = [],
31+
app_secret_fields: list[str] = [],
32+
unit_secret_fields: list[str] = [],
3333
) -> None:
3434
self._charm = charm
3535
self._relation_name = relation_name
@@ -54,17 +54,15 @@ def _peer_relation_data(self, scope: Scopes) -> data_interfaces.DataPeer:
5454
elif scope == UNIT_SCOPE:
5555
return self._peer_relation_unit
5656

57-
def get_value(self, scope: Scopes, key: str) -> typing.Optional[str]:
57+
def get_value(self, scope: Scopes, key: str) -> str | None:
5858
"""Get secret from the secret storage."""
5959
if scope not in typing.get_args(Scopes):
6060
raise ValueError("Unknown secret scope")
6161

6262
peers = self._charm.model.get_relation(self._relation_name)
6363
return self._peer_relation_data(scope).fetch_my_relation_field(peers.id, key)
6464

65-
def set_value(
66-
self, scope: Scopes, key: str, value: typing.Optional[str]
67-
) -> typing.Optional[str]:
65+
def set_value(self, scope: Scopes, key: str, value: str | None) -> str | None:
6866
"""Set secret from the secret storage."""
6967
if scope not in typing.get_args(Scopes):
7068
raise ValueError("Unknown secret scope")

common/common/relations/tls.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def __init__(self, charm_: "abstract_charm.MySQLRouterCharm") -> None:
177177
)
178178

179179
@property
180-
def _relation(self) -> typing.Optional[_Relation]:
180+
def _relation(self) -> _Relation | None:
181181
if not self._charm.model.get_relation(self.NAME):
182182
return
183183
return _Relation(
@@ -194,21 +194,21 @@ def certificate_saved(self) -> bool:
194194
return self._relation.certificate_saved
195195

196196
@property
197-
def key(self) -> typing.Optional[str]:
197+
def key(self) -> str | None:
198198
"""The TLS private key"""
199199
if self._relation is None:
200200
return None
201201
return self._relation.key
202202

203203
@property
204-
def certificate(self) -> typing.Optional[str]:
204+
def certificate(self) -> str | None:
205205
"""The TLS certificate"""
206206
if self._relation is None:
207207
return None
208208
return self._relation.certificate
209209

210210
@property
211-
def certificate_authority(self) -> typing.Optional[str]:
211+
def certificate_authority(self) -> str | None:
212212
"""The TLS certificate authority"""
213213
if self._relation is None:
214214
return None

0 commit comments

Comments
 (0)