@@ -21,6 +21,7 @@ def board(
2121 path : str = "" ,
2222 versioned : bool = True ,
2323 cache : "DEFAULT | None" = DEFAULT ,
24+ allow_pickle_read = None ,
2425 storage_options : "dict | None" = None ,
2526 board_factory : "callable | BaseBoard | None" = None ,
2627):
@@ -39,6 +40,14 @@ def board(
3940 Whether to use a cache. By default, pins attempts to select the right cache
4041 directory, given your filesystem. If None is passed, then no cache will be
4142 used. You can set the cache using the PINS_CACHE_DIR environment variable.
43+ allow_pickle_read: optional, bool
44+ Whether to allow reading pins that use the pickle protocol. Pickles are unsafe,
45+ and can execute arbitrary code. Only allow reading pickles if you trust the
46+ board to be able to execute python code on your computer.
47+
48+ You can enable reading pickles by setting this to True, or by setting the
49+ environment variable PINS_ALLOW_PICKLE_READ. If both are set, this argument
50+ takes precedence.
4251 storage_options:
4352 Additional options passed to the underlying filesystem created by
4453 fsspec.filesystem.
@@ -72,27 +81,32 @@ def board(
7281
7382 # construct board ----
7483
84+ pickle_kwargs = {"allow_pickle_read" : allow_pickle_read }
7585 # TODO: should use a registry or something
7686 if protocol == "rsc" and board_factory is None :
77- board = BoardRsConnect (path , fs , versioned )
87+ board = BoardRsConnect (path , fs , versioned , ** pickle_kwargs )
7888 elif board_factory is not None :
79- board = board_factory (path , fs , versioned )
89+ board = board_factory (path , fs , versioned , ** pickle_kwargs )
8090 else :
81- board = BaseBoard (path , fs , versioned )
91+ board = BaseBoard (path , fs , versioned , ** pickle_kwargs )
8292 return board
8393
8494
8595# TODO(#31): change file boards to unversioned once implemented
8696
8797
88- def board_folder (path , versioned = True ):
89- return board ("file" , path , versioned , cache = None )
98+ def board_folder (path , versioned = True , allow_pickle_read = None ):
99+ return board (
100+ "file" , path , versioned , cache = None , allow_pickle_read = allow_pickle_read
101+ )
90102
91103
92- def board_temp (versioned = True ):
104+ def board_temp (versioned = True , allow_pickle_read = None ):
93105 tmp_dir = tempfile .TemporaryDirectory ()
94106
95- board_obj = board ("file" , tmp_dir .name , versioned , cache = None )
107+ board_obj = board (
108+ "file" , tmp_dir .name , versioned , cache = None , allow_pickle_read = allow_pickle_read
109+ )
96110
97111 # TODO: this is necessary to ensure the temporary directory dir persists.
98112 # without maintaining a reference to it, it could be deleted after this
@@ -102,13 +116,17 @@ def board_temp(versioned=True):
102116 return board_obj
103117
104118
105- def board_local (versioned = True ):
119+ def board_local (versioned = True , allow_pickle_read = None ):
106120 path = get_data_dir ()
107121
108- return board ("file" , path , versioned , cache = None )
122+ return board (
123+ "file" , path , versioned , cache = None , allow_pickle_read = allow_pickle_read
124+ )
109125
110126
111- def board_github (org , repo , path = "" , versioned = True , cache = DEFAULT ):
127+ def board_github (
128+ org , repo , path = "" , versioned = True , cache = DEFAULT , allow_pickle_read = None
129+ ):
112130 """Returns a github pin board.
113131
114132 Parameters
@@ -144,11 +162,16 @@ def board_github(org, repo, path="", versioned=True, cache=DEFAULT):
144162 """
145163
146164 return board (
147- "github" , path , versioned , cache , storage_options = {"org" : org , "repo" : repo }
165+ "github" ,
166+ path ,
167+ versioned ,
168+ cache ,
169+ allow_pickle_read = allow_pickle_read ,
170+ storage_options = {"org" : org , "repo" : repo },
148171 )
149172
150173
151- def board_urls (path : str , pin_paths : dict , cache = DEFAULT ):
174+ def board_urls (path : str , pin_paths : dict , cache = DEFAULT , allow_pickle_read = None ):
152175 """
153176
154177 Example
@@ -175,10 +198,18 @@ def board_urls(path: str, pin_paths: dict, cache=DEFAULT):
175198 else :
176199 raise NotImplementedError ("Can't currently pass own cache object" )
177200
178- return BoardManual (path , fs , versioned = True , pin_paths = pin_paths )
201+ return BoardManual (
202+ path ,
203+ fs ,
204+ versioned = True ,
205+ allow_pickle_read = allow_pickle_read ,
206+ pin_paths = pin_paths ,
207+ )
179208
180209
181- def board_rsconnect (versioned = True , server_url = None , api_key = None , cache = DEFAULT ):
210+ def board_rsconnect (
211+ versioned = True , server_url = None , api_key = None , cache = DEFAULT , allow_pickle_read = None
212+ ):
182213 """
183214
184215 Parameters
@@ -196,9 +227,9 @@ def board_rsconnect(versioned=True, server_url=None, api_key=None, cache=DEFAULT
196227 server_url = os .environ .get ("CONNECT_SERVER" )
197228
198229 kwargs = dict (server_url = server_url , api_key = api_key )
199- return board ("rsc" , "" , versioned , storage_options = kwargs )
230+ return board ("rsc" , "" , versioned , cache , allow_pickle_read , storage_options = kwargs )
200231
201232
202- def board_s3 (path , versioned = True ):
233+ def board_s3 (path , versioned = True , cache = DEFAULT , allow_pickle_read = None ):
203234 # TODO: user should be able to specify storage options here?
204- return board ("s3" , path , versioned )
235+ return board ("s3" , path , versioned , cache , allow_pickle_read )
0 commit comments