1414
1515from attrs import define
1616from attrs import field
17+ from typing_extensions import deprecated
1718from upath import UPath
1819from upath ._stat import UPathStatResult
1920
2829from _pytask .typing import no_default
2930
3031if TYPE_CHECKING :
32+ from io import BufferedReader
33+ from io import BufferedWriter
34+
3135 from _pytask .mark import Mark
3236 from _pytask .models import NodeInfo
3337 from _pytask .tree_util import PyTree
4044 "PythonNode" ,
4145 "Task" ,
4246 "TaskWithoutPath" ,
47+ "get_state_of_path" ,
4348]
4449
4550
@@ -145,7 +150,7 @@ def signature(self) -> str:
145150
146151 def state (self ) -> str | None :
147152 """Return the state of the node."""
148- return _get_state (self .path )
153+ return get_state_of_path (self .path )
149154
150155 def execute (self , ** kwargs : Any ) -> Any :
151156 """Execute the task."""
@@ -188,7 +193,7 @@ def state(self) -> str | None:
188193 The state is given by the modification timestamp.
189194
190195 """
191- return _get_state (self .path )
196+ return get_state_of_path (self .path )
192197
193198 def load (self , is_product : bool = False ) -> Path : # noqa: ARG002
194199 """Load the value."""
@@ -310,12 +315,18 @@ class PickleNode(PPathNode):
310315 The path to the file.
311316 attributes: dict[Any, Any]
312317 A dictionary to store additional information of the task.
318+ serializer
319+ A function to serialize the object. Defaults to :func:`pickle.dump`.
320+ deserializer
321+ A function to deserialize the object. Defaults to :func:`pickle.load`.
313322
314323 """
315324
316325 path : Path
317326 name : str = ""
318327 attributes : dict [Any , Any ] = field (factory = dict )
328+ serializer : Callable [[Any , BufferedWriter ], None ] = field (default = pickle .dump )
329+ deserializer : Callable [[BufferedReader ], Any ] = field (default = pickle .load )
319330
320331 @property
321332 def signature (self ) -> str :
@@ -332,17 +343,17 @@ def from_path(cls, path: Path) -> PickleNode:
332343 return cls (name = path .as_posix (), path = path )
333344
334345 def state (self ) -> str | None :
335- return _get_state (self .path )
346+ return get_state_of_path (self .path )
336347
337348 def load (self , is_product : bool = False ) -> Any :
338349 if is_product :
339350 return self
340351 with self .path .open ("rb" ) as f :
341- return pickle . load (f ) # noqa: S301
352+ return self . deserializer (f )
342353
343354 def save (self , value : Any ) -> None :
344355 with self .path .open ("wb" ) as f :
345- pickle . dump (value , f )
356+ self . serializer (value , f )
346357
347358
348359@define (kw_only = True )
@@ -387,7 +398,7 @@ def collect(self) -> list[Path]:
387398 return list (self .root_dir .glob (self .pattern )) # type: ignore[union-attr]
388399
389400
390- def _get_state (path : Path ) -> str | None :
401+ def get_state_of_path (path : Path ) -> str | None :
391402 """Get state of a path.
392403
393404 A simple function to handle local and remote files.
@@ -411,3 +422,13 @@ def _get_state(path: Path) -> str | None:
411422 return stat .as_info ().get ("ETag" , "0" )
412423 msg = "Unknown stat object."
413424 raise NotImplementedError (msg )
425+
426+
427+ @deprecated ("Use 'pytask.get_state_of_path' instead." )
428+ def _get_state (path : Path ) -> str | None :
429+ """Get state of a path.
430+
431+ A simple function to handle local and remote files.
432+
433+ """
434+ return get_state_of_path (path )
0 commit comments