Skip to content

Commit b363644

Browse files
committed
Add reprs for py classes and dataclass-esque constructor for WriteOptions
1 parent ebb5a2f commit b363644

File tree

4 files changed

+103
-7
lines changed

4 files changed

+103
-7
lines changed

python/conftest.py

+6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import urllib.parse
44

55
import fsspec
6+
from hdfs_native import Client
67
import pytest
78

89
from hdfs_native.fsspec import HdfsFileSystem
@@ -39,6 +40,11 @@ def minidfs():
3940
child.kill()
4041

4142

43+
@pytest.fixture(scope="module")
44+
def client(minidfs: str) -> Client:
45+
return Client(minidfs)
46+
47+
4248
@pytest.fixture(scope="module")
4349
def fs(minidfs: str) -> HdfsFileSystem:
4450
url = urllib.parse.urlparse(minidfs)

python/hdfs_native/_internal.pyi

+9
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,15 @@ class WriteOptions:
3030
overwrite: bool
3131
create_parent: bool
3232

33+
def __init__(
34+
self,
35+
block_size: Optional[int] = None,
36+
replication: Optional[int] = None,
37+
permission: Optional[int] = None,
38+
overwrite: Optional[bool] = None,
39+
create_parent: Optional[bool] = None,
40+
): ...
41+
3342
class RawFileReader:
3443
def file_length(self) -> int:
3544
"""Returns the size of the file"""

python/src/lib.rs

+70-3
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,25 @@ impl From<FileStatus> for PyFileStatus {
5050
}
5151
}
5252

53+
#[pymethods]
54+
impl PyFileStatus {
55+
/// Return a dataclass-esque format for the repr
56+
fn __repr__(&self) -> String {
57+
format!("FileStatus(path='{}', length={}, isdir={}, permission={}, owner={}, group={}, modification_time={}, access_time={}, replication={}, blocksize={})",
58+
self.path,
59+
self.length,
60+
self.isdir,
61+
self.permission,
62+
self.owner,
63+
self.group,
64+
self.modification_time,
65+
self.access_time,
66+
self.replication.map(|r| r.to_string()).unwrap_or("None".to_string()),
67+
self.blocksize.map(|r| r.to_string()).unwrap_or("None".to_string())
68+
)
69+
}
70+
}
71+
5372
#[pyclass(name = "FileStatusIter")]
5473
struct PyFileStatusIter {
5574
inner: ListStatusIterator,
@@ -96,6 +115,21 @@ impl From<ContentSummary> for PyContentSummary {
96115
}
97116
}
98117

118+
#[pymethods]
119+
impl PyContentSummary {
120+
/// Return a dataclass-esque format for the repr
121+
fn __repr__(&self) -> String {
122+
format!("ContentSummary(length={}, file_count={}, directory_count={}, quota={}, space_consumed={}, space_quota={})",
123+
self.length,
124+
self.file_count,
125+
self.directory_count,
126+
self.quota,
127+
self.space_consumed,
128+
self.space_quota,
129+
)
130+
}
131+
}
132+
99133
#[pyclass]
100134
struct RawFileReader {
101135
inner: FileReader,
@@ -173,9 +207,42 @@ impl From<WriteOptions> for PyWriteOptions {
173207
#[pymethods]
174208
impl PyWriteOptions {
175209
#[new]
176-
#[pyo3(signature = ())]
177-
pub fn new() -> Self {
178-
Self::from(WriteOptions::default())
210+
pub fn new(
211+
block_size: Option<u64>,
212+
replication: Option<u32>,
213+
permission: Option<u32>,
214+
overwrite: Option<bool>,
215+
create_parent: Option<bool>,
216+
) -> Self {
217+
let mut write_options = WriteOptions::default();
218+
if let Some(block_size) = block_size {
219+
write_options = write_options.block_size(block_size);
220+
}
221+
if let Some(replication) = replication {
222+
write_options = write_options.replication(replication);
223+
}
224+
if let Some(permission) = permission {
225+
write_options = write_options.permission(permission);
226+
}
227+
if let Some(overwrite) = overwrite {
228+
write_options = write_options.overwrite(overwrite);
229+
}
230+
if let Some(create_parent) = create_parent {
231+
write_options = write_options.create_parent(create_parent);
232+
}
233+
234+
PyWriteOptions::from(write_options)
235+
}
236+
237+
/// Return a dataclass-esque format for the repr
238+
fn __repr__(&self) -> String {
239+
format!("WriteOptions(block_size={}, replication={}, permission={}, overwrite={}, create_parent={})",
240+
self.block_size.map(|x| x.to_string()).unwrap_or("None".to_string()),
241+
self.replication.map(|x| x.to_string()).unwrap_or("None".to_string()),
242+
self.permission,
243+
self.overwrite,
244+
self.create_parent
245+
)
179246
}
180247
}
181248

python/tests/test_integration.py

+18-4
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
from hdfs_native import Client, WriteOptions
44

55

6-
def test_integration(minidfs: str):
7-
client = Client(minidfs)
8-
client.create("/testfile", WriteOptions()).close()
6+
def test_integration(client: Client):
7+
client.create("/testfile").close()
98
file_info = client.get_file_info("/testfile")
109

1110
assert file_info.path == "/testfile"
@@ -25,7 +24,7 @@ def test_integration(minidfs: str):
2524
file_list = list(client.list_status("/", False))
2625
assert len(file_list) == 0
2726

28-
with client.create("/testfile", WriteOptions()) as file:
27+
with client.create("/testfile") as file:
2928
data = io.BytesIO()
3029

3130
for i in range(0, 32 * 1024 * 1024):
@@ -101,3 +100,18 @@ def test_integration(minidfs: str):
101100
assert content_summary.length == 33 * 1024 * 1024 * 4
102101

103102
client.delete("/testfile", False)
103+
104+
105+
def test_write_options(client: Client):
106+
with client.create("/testfile") as file:
107+
file.write(b"abcd")
108+
109+
client.create(
110+
"/testfile",
111+
WriteOptions(overwrite=True, permission=0o700, block_size=1024 * 1024),
112+
).close()
113+
114+
file_info = client.get_file_info("/testfile")
115+
assert file_info.length == 0
116+
assert file_info.permission == 0o700
117+
assert file_info.blocksize == 1024 * 1024

0 commit comments

Comments
 (0)