mirror of
https://github.com/clearml/clearml
synced 2025-03-03 10:42:00 +00:00
Add get_parameters cast back to original type
This commit is contained in:
parent
296cb7d899
commit
cf9938c490
@ -449,7 +449,7 @@ class _Arguments(object):
|
||||
if descriptions:
|
||||
descriptions = dict((prefix+k, v) for k, v in descriptions.items())
|
||||
if param_types:
|
||||
param_types = dict((prefix+k, v) for k, v in param_types.items())
|
||||
param_types = dict((prefix + k, v) for k, v in param_types.items())
|
||||
# this will only set the specific section
|
||||
self._task.update_parameters(
|
||||
dictionary,
|
||||
|
@ -28,7 +28,7 @@ import six
|
||||
from six.moves.urllib.parse import quote
|
||||
|
||||
from ...utilities.locks import RLock as FileRLock
|
||||
from ...utilities.proxy_object import verify_basic_type
|
||||
from ...utilities.proxy_object import verify_basic_type, cast_basic_type, get_basic_type
|
||||
from ...binding.artifacts import Artifacts
|
||||
from ...backend_interface.task.development.worker import DevWorker
|
||||
from ...backend_interface.session import SendError
|
||||
@ -927,8 +927,8 @@ class Task(IdObjectBase, AccessMixin, SetupUploadMixin):
|
||||
|
||||
self._edit(execution=self.data.execution)
|
||||
|
||||
def get_parameters(self, backwards_compatibility=True):
|
||||
# type: (bool) -> (Optional[dict])
|
||||
def get_parameters(self, backwards_compatibility=True, cast=False):
|
||||
# type: (bool, bool) -> (Optional[dict])
|
||||
"""
|
||||
Get the parameters for a Task. This method returns a complete group of key-value parameter pairs, but does not
|
||||
support parameter descriptions (the result is a dictionary of key-value pairs).
|
||||
@ -938,6 +938,8 @@ class Task(IdObjectBase, AccessMixin, SetupUploadMixin):
|
||||
:param backwards_compatibility: If True (default) parameters without section name
|
||||
(API version < 2.9, clearml-server < 0.16) will be at dict root level.
|
||||
If False, parameters without section name, will be nested under "Args/" key.
|
||||
:param cast: If True, cast the parameter to the original type. Default False,
|
||||
values are returned in their string representation
|
||||
|
||||
:return: dict of the task parameters, all flattened to key/value.
|
||||
Different sections with key prefix "section/"
|
||||
@ -951,14 +953,16 @@ class Task(IdObjectBase, AccessMixin, SetupUploadMixin):
|
||||
if not backwards_compatibility:
|
||||
for section in hyperparams:
|
||||
for key, section_param in hyperparams[section].items():
|
||||
parameters['{}/{}'.format(section, key)] = section_param.value
|
||||
parameters['{}/{}'.format(section, key)] = \
|
||||
cast_basic_type(section_param.value, section_param.type) if cast else section_param.value
|
||||
else:
|
||||
for section in hyperparams:
|
||||
for key, section_param in hyperparams[section].items():
|
||||
v = cast_basic_type(section_param.value, section_param.type) if cast else section_param.value
|
||||
if section_param.type == 'legacy' and section in (self._legacy_parameters_section_name, ):
|
||||
parameters['{}'.format(key)] = section_param.value
|
||||
parameters['{}'.format(key)] = v
|
||||
else:
|
||||
parameters['{}/{}'.format(section, key)] = section_param.value
|
||||
parameters['{}/{}'.format(section, key)] = v
|
||||
|
||||
return parameters
|
||||
|
||||
@ -1086,7 +1090,7 @@ class Task(IdObjectBase, AccessMixin, SetupUploadMixin):
|
||||
section = hyperparams.get(section_name, dict())
|
||||
org_param = org_hyperparams.get(section_name, dict()).get(key, None)
|
||||
param_type = params_types[org_k] if org_k in params_types else (
|
||||
org_param.type if org_param is not None else type(v) if v is not None else None
|
||||
org_param.type if org_param is not None else get_basic_type(v) if v is not None else None
|
||||
)
|
||||
if param_type and not isinstance(param_type, str):
|
||||
param_type = param_type.__name__ if hasattr(param_type, '__name__') else str(param_type)
|
||||
|
@ -1854,16 +1854,19 @@ class Task(_Task):
|
||||
j['variant'], {'last': j['value'], 'min': j['min_value'], 'max': j['max_value']})
|
||||
return scalar_metrics
|
||||
|
||||
def get_parameters_as_dict(self):
|
||||
# type: () -> Dict
|
||||
def get_parameters_as_dict(self, cast=False):
|
||||
# type: (bool) -> Dict
|
||||
"""
|
||||
Get the Task parameters as a raw nested dictionary.
|
||||
|
||||
.. note::
|
||||
The values are not parsed. They are returned as is.
|
||||
If `cast` is False (default) The values are not parsed. They are returned as is.
|
||||
|
||||
:param cast: If True, cast the parameter to the original type. Default False,
|
||||
values are returned in their string representation
|
||||
|
||||
"""
|
||||
return naive_nested_from_flat_dictionary(self.get_parameters())
|
||||
return naive_nested_from_flat_dictionary(self.get_parameters(cast=cast))
|
||||
|
||||
def set_parameters_as_dict(self, dictionary):
|
||||
# type: (Dict) -> None
|
||||
|
@ -1,7 +1,9 @@
|
||||
import itertools
|
||||
import json
|
||||
from copy import copy
|
||||
|
||||
import six
|
||||
import yaml
|
||||
|
||||
|
||||
class ProxyDictPostWrite(dict):
|
||||
@ -91,6 +93,59 @@ def verify_basic_type(a_dict_list, basic_types=None):
|
||||
all(verify_basic_type(v) for v in a_dict_list.values())
|
||||
|
||||
|
||||
def cast_basic_type(value, type_str):
|
||||
if not type_str:
|
||||
return value
|
||||
|
||||
basic_types = {str(getattr(v, '__name__', v)): v for v in (float, int, bool, str, list, tuple, dict)}
|
||||
|
||||
parts = type_str.split('/')
|
||||
# nested = len(parts) > 1
|
||||
|
||||
if parts[0] in ('list', 'tuple'):
|
||||
v = '[' + value.lstrip('[(').rstrip('])') + ']'
|
||||
v = yaml.load(v, Loader=yaml.SafeLoader)
|
||||
return basic_types.get(parts[0])(v)
|
||||
elif parts[0] in ('dict', ):
|
||||
try:
|
||||
return json.loads(value)
|
||||
except Exception:
|
||||
pass
|
||||
return value
|
||||
|
||||
t = basic_types.get(str(type_str).lower().strip(), False)
|
||||
if t is not False:
|
||||
# noinspection PyBroadException
|
||||
try:
|
||||
return t(value)
|
||||
except Exception:
|
||||
return value
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def get_basic_type(value):
|
||||
basic_types = (float, int, bool, six.string_types, list, tuple, dict)
|
||||
|
||||
if isinstance(value, (list, tuple)) and value:
|
||||
tv = type(value)
|
||||
t = type(value[0])
|
||||
if all(t == type(v) for v in value):
|
||||
return '{}/{}'.format(str(getattr(tv, '__name__', tv)), str(getattr(t, '__name__', t)))
|
||||
elif isinstance(value, dict) and value:
|
||||
t = type(list(value.values())[0])
|
||||
if all(t == type(v) for v in value.values()):
|
||||
return 'dict/{}'.format(str(getattr(t, '__name__', t)))
|
||||
|
||||
# it might be an empty list/dict/tuple
|
||||
t = type(value)
|
||||
if isinstance(value, basic_types):
|
||||
return str(getattr(t, '__name__', t))
|
||||
|
||||
# we are storing it, even though we will not be able to restore it
|
||||
return str(getattr(t, '__name__', t))
|
||||
|
||||
|
||||
def flatten_dictionary(a_dict, prefix='', sep='/'):
|
||||
flat_dict = {}
|
||||
basic_types = (float, int, bool, six.string_types, )
|
||||
|
Loading…
Reference in New Issue
Block a user