22"""
33import os
44from contextlib import contextmanager as contextmanager
5+ import threading
56
67_global_config = {
78 'assume_finite' : bool (os .environ .get ('SKLEARN_ASSUME_FINITE' , False )),
89 'working_memory' : int (os .environ .get ('SKLEARN_WORKING_MEMORY' , 1024 )),
910 'print_changed_only' : True ,
1011 'display' : 'text' ,
1112}
13+ _threadlocal = threading .local ()
14+
15+
16+ def _get_threadlocal_config ():
17+ """Get a threadlocal **mutable** configuration. If the configuration
18+ does not exist, copy the default global configuration."""
19+ if not hasattr (_threadlocal , 'global_config' ):
20+ _threadlocal .global_config = _global_config .copy ()
21+ return _threadlocal .global_config
1222
1323
1424def get_config ():
@@ -24,7 +34,9 @@ def get_config():
2434 config_context : Context manager for global scikit-learn configuration.
2535 set_config : Set global scikit-learn configuration.
2636 """
27- return _global_config .copy ()
37+ # Return a copy of the threadlocal configuration so that users will
38+ # not be able to modify the configuration with the returned dict.
39+ return _get_threadlocal_config ().copy ()
2840
2941
3042def set_config (assume_finite = None , working_memory = None ,
@@ -72,14 +84,16 @@ def set_config(assume_finite=None, working_memory=None,
7284 config_context : Context manager for global scikit-learn configuration.
7385 get_config : Retrieve current values of the global configuration.
7486 """
87+ local_config = _get_threadlocal_config ()
88+
7589 if assume_finite is not None :
76- _global_config ['assume_finite' ] = assume_finite
90+ local_config ['assume_finite' ] = assume_finite
7791 if working_memory is not None :
78- _global_config ['working_memory' ] = working_memory
92+ local_config ['working_memory' ] = working_memory
7993 if print_changed_only is not None :
80- _global_config ['print_changed_only' ] = print_changed_only
94+ local_config ['print_changed_only' ] = print_changed_only
8195 if display is not None :
82- _global_config ['display' ] = display
96+ local_config ['display' ] = display
8397
8498
8599@contextmanager
@@ -120,8 +134,7 @@ def config_context(**new_config):
120134 Notes
121135 -----
122136 All settings, not just those presently modified, will be returned to
123- their previous values when the context manager is exited. This is not
124- thread-safe.
137+ their previous values when the context manager is exited.
125138
126139 Examples
127140 --------
@@ -141,7 +154,7 @@ def config_context(**new_config):
141154 set_config : Set global scikit-learn configuration.
142155 get_config : Retrieve current values of the global configuration.
143156 """
144- old_config = get_config (). copy ()
157+ old_config = get_config ()
145158 set_config (** new_config )
146159
147160 try :
0 commit comments