Skip to content

Commit 3a49fbe

Browse files
Miauwkeruyunzheng
authored andcommitted
Send raw command string instead of a dictionary
1 parent 04aec16 commit 3a49fbe

File tree

4 files changed

+51
-38
lines changed

4 files changed

+51
-38
lines changed

flow/record/fieldtypes/__init__.py

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -736,10 +736,11 @@ class command(FieldType):
736736
executable: path | None = None
737737
args: list[str] | None = None
738738

739+
_raw: str | None = None
739740
_path_type: type[path] = None
740-
_posix: bool
741+
_posix: bool = True
741742

742-
def __new__(cls, value: str):
743+
def __new__(cls, value: str | None):
743744
if cls is not command:
744745
return super().__new__(cls)
745746

@@ -757,17 +758,12 @@ def __new__(cls, value: str):
757758
cls = windows_command if windows else posix_command
758759
return super().__new__(cls)
759760

760-
def __init__(self, value: str | tuple[str, tuple[str]] | None):
761+
def __init__(self, value: str | None):
761762
if value is None:
762763
return
763764

764-
if isinstance(value, str):
765-
self.executable, self.args = self._split(value)
766-
return
767-
768-
executable, self.args = value
769-
self.executable = self._path_type(executable)
770-
self.args = list(self.args)
765+
self._raw = value
766+
self.executable, self.args = self._split(self._raw)
771767

772768
def __repr__(self) -> str:
773769
return f"(executable={self.executable!r}, args={self.args})"
@@ -776,30 +772,29 @@ def __eq__(self, other: object) -> bool:
776772
if isinstance(other, command):
777773
return self.executable == other.executable and self.args == other.args
778774
if isinstance(other, str):
779-
return self._join() == other
775+
return self._raw == other
780776
if isinstance(other, (tuple, list)):
781777
return self.executable == other[0] and self.args == list(other[1:])
782778

783779
return False
784780

785-
def _split(self, value: str) -> tuple[str, list[str]]:
781+
def _split(self, value: str) -> tuple[path, list[str]]:
786782
executable, *args = shlex.split(value, posix=self._posix)
787783
executable = executable.strip("'\" ")
788784

789785
return self._path_type(executable), args
790786

791787
def _join(self) -> str:
792-
return shlex.join([str(self.executable), *self.args])
788+
return self._raw
793789

794-
def _pack(self) -> tuple[tuple[str, list], str]:
790+
def _pack(self) -> tuple[str, int]:
795791
command_type = TYPE_WINDOWS if isinstance(self, windows_command) else TYPE_POSIX
796792
if self.executable:
797-
_exec, _ = self.executable._pack()
798-
return ((_exec, self.args), command_type)
793+
return (self._raw, command_type)
799794
return (None, command_type)
800795

801796
@classmethod
802-
def _unpack(cls, data: tuple[tuple[str, tuple] | None, int]) -> command:
797+
def _unpack(cls, data: tuple[str | None, int]) -> command:
803798
_value, _type = data
804799
if _type == TYPE_WINDOWS:
805800
return windows_command(_value)
@@ -824,18 +819,8 @@ class windows_command(command):
824819
_posix = False
825820
_path_type = windows_path
826821

827-
def _split(self, value: str) -> tuple[str, list[str]]:
828-
executable, args = super()._split(value)
829-
if args:
830-
args = [" ".join(args)]
822+
def _split(self, value: str) -> tuple[path, list[str]]:
823+
executable, _args = super()._split(value)
824+
args = [" ".join(_args)] if _args else _args
831825

832826
return executable, args
833-
834-
def _join(self) -> str:
835-
arg = f" {self.args[0]}" if self.args else ""
836-
executable_str = str(self.executable)
837-
838-
if " " in executable_str:
839-
return f"'{executable_str}'{arg}"
840-
841-
return f"{executable_str}{arg}"

flow/record/jsonpacker.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,7 @@ def pack_obj(self, obj: Any) -> dict | str:
7575
if isinstance(obj, fieldtypes.path):
7676
return str(obj)
7777
if isinstance(obj, fieldtypes.command):
78-
return {
79-
"executable": obj.executable,
80-
"args": obj.args,
81-
}
78+
return obj._raw
8279

8380
raise TypeError(f"Unpackable type {type(obj)}")
8481

tests/_utils.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,16 @@ def generate_plain_records(count: int = 100) -> Iterator[Record]:
4242

4343
for i in range(count):
4444
yield TestRecord(number=i, dt=datetime.datetime.now(datetime.timezone.utc))
45+
46+
47+
def generate_command_records(count: int = 100) -> Iterator[Record]:
48+
TestRecord = RecordDescriptor(
49+
"test/addapter/command",
50+
[
51+
("uint32", "number"),
52+
("command", "data"),
53+
],
54+
)
55+
56+
for i in range(count):
57+
yield TestRecord(number=i, data=f"/path/to/file {i}")

tests/adapter/test_json.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,42 @@
11
from __future__ import annotations
22

33
import json
4-
from typing import TYPE_CHECKING
4+
from enum import Enum, auto
5+
from typing import TYPE_CHECKING, Callable
56

67
import pytest
78

89
from flow.record import RecordReader, RecordWriter
9-
from tests._utils import generate_records
10+
from tests._utils import generate_command_records, generate_records
1011

1112
if TYPE_CHECKING:
13+
from collections.abc import Iterator
1214
from pathlib import Path
1315

16+
from flow.record import Record
1417

15-
def test_json_adapter(tmp_path: Path) -> None:
18+
19+
class GeneratorType(Enum):
20+
RECORDS = auto()
21+
COMMAND = auto()
22+
23+
24+
FUNCTIONS = {
25+
GeneratorType.RECORDS: generate_records,
26+
GeneratorType.COMMAND: generate_command_records,
27+
}
28+
29+
30+
@pytest.mark.parametrize("generator_function", FUNCTIONS.keys())
31+
def test_json_adapter(generator_function: GeneratorType, tmp_path: Path) -> None:
1632
json_file = tmp_path.joinpath("records.json")
1733
record_adapter_path = f"jsonfile://{json_file}"
1834
writer = RecordWriter(record_adapter_path)
1935
nr_records = 1337
2036

21-
for record in generate_records(nr_records):
37+
gen_func: Callable[[int], Iterator[Record]] = FUNCTIONS.get(generator_function)
38+
39+
for record in gen_func(nr_records):
2240
writer.write(record)
2341
writer.flush()
2442

0 commit comments

Comments
 (0)