Skip to content

Commit b684ec2

Browse files
committed
chore: an AI's inadequate pass at adding strict typing
1 parent bfbac98 commit b684ec2

112 files changed

Lines changed: 1954 additions & 1606 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

examples/custom_http_endpoint.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,22 @@
77
"""
88

99
import time
10-
import os
1110
import json
1211

1312
from dsf.connections import CommandConnection
14-
from dsf.http import HttpEndpointConnection, HttpResponseType
13+
from dsf.http import HttpEndpointConnection, HttpEndpointUnixSocket, HttpResponseType
1514
from dsf.object_model import HttpEndpointType
1615

1716

18-
async def respond_something(http_endpoint_connection: HttpEndpointConnection):
17+
async def respond_something(http_endpoint_connection: HttpEndpointConnection) -> None:
1918
r = await http_endpoint_connection.read_request()
2019
if (len(r.body) > 0):
21-
data = json.loads(r.body)
20+
json.loads(r.body)
2221
await http_endpoint_connection.send_response(200, "so happy you asked for it!", HttpResponseType.PlainText)
2322
http_endpoint_connection.close()
2423

2524

26-
def custom_http_endpoint():
25+
def custom_http_endpoint() -> tuple[CommandConnection, HttpEndpointUnixSocket]:
2726
cmd_conn = CommandConnection(debug=True)
2827
cmd_conn.connect()
2928

@@ -39,11 +38,14 @@ def custom_http_endpoint():
3938

4039

4140
if __name__ == "__main__":
41+
cmd_conn: CommandConnection | None = None
42+
endpoint: HttpEndpointUnixSocket | None = None
4243
try:
4344
cmd_conn, endpoint = custom_http_endpoint()
4445
# This just simulates doing other things as the new endpoint handler runs async
4546
time.sleep(1800)
4647
finally:
4748
if endpoint is not None:
4849
endpoint.close()
49-
cmd_conn.close()
50+
if cmd_conn is not None:
51+
cmd_conn.close()

src/dsf/__init__.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
1-
__version__ = "3.6.0"
1+
__version__: str = "3.6.0"
22

33
import json
44
import os
55

66
# Default socket file path
7-
SOCKET_FILE = "/run/dsf/dcs.sock"
7+
SOCKET_FILE: str = "/run/dsf/dcs.sock"
88

99
# Try to read socket file path from config
1010
config_path = "/opt/dsf/conf/config.json"
1111
if os.path.exists(config_path):
1212
try:
1313
with open(config_path, 'r') as f:
1414
config = json.load(f)
15-
socket_dir = config.get("SocketDirectory", "/run/dsf")
16-
socket_file = config.get("SocketFile", "dcs.sock")
15+
socket_dir = str(config.get("SocketDirectory", "/run/dsf"))
16+
socket_file = str(config.get("SocketFile", "dcs.sock"))
1717
SOCKET_FILE = os.path.join(socket_dir, socket_file)
1818
except (json.JSONDecodeError, IOError):
1919
pass # Use default if config file is invalid or inaccessible
2020

2121
# allowed connection per unix server
22-
DEFAULT_BACKLOG = 4
22+
DEFAULT_BACKLOG: int = 4
2323

2424
# DSF protocol version
25-
PROTOCOL_VERSION = 12
25+
PROTOCOL_VERSION: int = 12
2626

2727
from . import commands, connections, http, object_model

src/dsf/commands/base_command.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ class BaseCommand:
22
"""Base class of a command."""
33

44
@classmethod
5-
def from_json(cls, data):
5+
def from_json(cls, data: dict[str, object]) -> "BaseCommand":
66
"""Deserialize an instance of this class from a JSON deserialized dictionary"""
7-
return cls(**data)
7+
command = data.get("command", "")
8+
kwargs = {key: value for key, value in data.items() if key != "command"}
9+
return cls(command=str(command), **kwargs)
810

9-
def __init__(self, command: str, **kwargs):
11+
def __init__(self, command: str, **kwargs: object) -> None:
1012
self.command = command
1113
for key, value in kwargs.items():
1214
self.__dict__[key] = value

src/dsf/commands/code.py

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,23 @@ class Code(BaseCommand):
1313
"""A parsed representation of a generic G/M/T-code"""
1414

1515
@classmethod
16-
def from_json(cls, data):
16+
def from_json(cls, data: dict[str, object] | str) -> "Code":
1717
"""Deserialize an instance of this class from JSON deserialized dictionary"""
18-
data["result"] = None if data["result"] is None else list(map(Message.from_json, data["result"]))
19-
data["parameters"] = list(map(CodeParameter.from_json, data["parameters"]))
18+
if isinstance(data, str):
19+
raise TypeError("Code.from_json expects a decoded JSON dictionary")
20+
data = dict(data)
21+
result = data.get("result")
22+
parameters = data.get("parameters")
23+
data["result"] = None if not isinstance(result, list) else [Message.from_json(item)
24+
for item in result if isinstance(item, dict)]
25+
data["parameters"] = [] if not isinstance(parameters, list) else [CodeParameter.from_json(
26+
item) for item in parameters if isinstance(item, dict)]
2027
if "channel" in data:
2128
data["channel"] = CodeChannel(data["channel"])
22-
return cls(**data)
29+
command = str(data.pop("command", ""))
30+
return cls(command=command, **data)
2331

24-
def __init__(self, **kwargs):
32+
def __init__(self, command: str = "", **kwargs: object):
2533
# The connection ID this code was received from. If this is 0, the code originates from an internal DCS task
2634
# Usually there is no need to populate this property.
2735
# It is internally overwritten by the control server on receipt
@@ -73,14 +81,14 @@ def __init__(self, **kwargs):
7381
# List of parsed code parameters
7482
self.parameters: List[CodeParameter] = []
7583

76-
super().__init__(**kwargs)
84+
super().__init__(command=command, **kwargs)
7785

7886
@property
7987
def is_from_file_channel(self) -> bool:
8088
"""Check if this code is from a file channel"""
8189
return self.channel is CodeChannel.File or self.channel is CodeChannel.File2
8290

83-
def parameter(self, letter: str, default=None):
91+
def parameter(self, letter: str, default: object = None) -> CodeParameter | None:
8492
"""Retrieve the parameter whose letter equals c or generate a default parameter"""
8593
letter = letter.upper()
8694
param = [param for param in self.parameters if param.letter.upper() == letter]
@@ -90,7 +98,7 @@ def parameter(self, letter: str, default=None):
9098
return CodeParameter.simple_param(letter, default)
9199
return None
92100

93-
def get_unprecedented_string(self, quote: bool = False):
101+
def get_unprecedented_string(self, quote: bool = False) -> str:
94102
"""
95103
Reconstruct an unprecedented string from the parameter list or
96104
retrieve the parameter which does not have a letter assigned.
@@ -103,7 +111,7 @@ def get_unprecedented_string(self, quote: bool = False):
103111
str_list.append(f"{param.letter}{param.string_value}")
104112
return " ".join(str_list)
105113

106-
def __str__(self):
114+
def __str__(self) -> str:
107115
"""Convert the parsed code back to a text-based G/M/T-code"""
108116
if self.keyword != KeywordType.KeywordNone:
109117
if self.keywordArgument is not None:
@@ -129,7 +137,7 @@ def __str__(self):
129137

130138
return "".join(str_list)
131139

132-
def short_str(self):
140+
def short_str(self) -> str:
133141
"""Convert only the command portion to a text-based G/M/T-code (e.g. G28)"""
134142
if self.type == CodeType.Comment:
135143
return "(comment)"
@@ -143,7 +151,7 @@ def short_str(self):
143151

144152
return f"{prefix}{self.type}"
145153

146-
def keyword_to_str(self):
154+
def keyword_to_str(self) -> str:
147155
"""Convert the keyword to a string"""
148156
return {
149157
KeywordType.If: "if",
@@ -157,7 +165,7 @@ def keyword_to_str(self):
157165
KeywordType.Set: "set",
158166
KeywordType.Echo: "echo",
159167
KeywordType.Global: "global",
160-
}.get(self.keyword)
168+
}[self.keyword]
161169

162-
def is_flag_set(self, flag: CodeFlags):
170+
def is_flag_set(self, flag: CodeFlags) -> bool:
163171
return self.flags & flag != 0

src/dsf/commands/code_channel.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,5 @@ class CodeChannel(str, Enum):
5454
DEFAULT_CHANNEL = SBC
5555

5656
@staticmethod
57-
def list():
58-
return list(map(lambda cc: cc.value, CodeChannel))
57+
def list() -> list["CodeChannel"]:
58+
return list(CodeChannel)

0 commit comments

Comments
 (0)