From 30c5945f1cb4a5f2ef37ec723c1f1a433b9ae576 Mon Sep 17 00:00:00 2001 From: Fabio Caccamo Date: Thu, 3 Oct 2019 18:42:44 +0200 Subject: [PATCH] Refactored io dict and utils. --- benedict/dicts/io.py | 76 +++++++++++++++++++-------------------- benedict/utils/io_util.py | 11 ++++++ 2 files changed, 48 insertions(+), 39 deletions(-) diff --git a/benedict/dicts/io.py b/benedict/dicts/io.py index 33c6c8c..e88c13e 100644 --- a/benedict/dicts/io.py +++ b/benedict/dicts/io.py @@ -4,16 +4,14 @@ from benedict.utils import io_util from six import string_types, text_type -import os - class IODict(dict): def __init__(self, *args, **kwargs): - # if first argument is string, + # if first argument is data-string, # try to decode it using all decoders. if len(args) and isinstance(args[0], string_types): - d = IODict._from_any_string(args[0]) + d = IODict._from_any_data_string(args[0]) if d and isinstance(d, dict): args = list(args) args[0] = d @@ -23,15 +21,10 @@ class IODict(dict): super(IODict, self).__init__(*args, **kwargs) @staticmethod - def _load_and_decode(s, decoder, **kwargs): + def _decode(s, decoder, **kwargs): d = None try: - if s.startswith('http://') or s.startswith('https://'): - content = io_util.read_url(s) - elif os.path.isfile(s): - content = io_util.read_file(s) - else: - content = s + content = io_util.read_content(s) # decode content using the given decoder data = decoder(content, **kwargs) if isinstance(data, dict): @@ -48,66 +41,71 @@ class IODict(dict): return d @staticmethod - def _encode_and_save(d, encoder, filepath=None, **kwargs): + def _encode(d, encoder, filepath=None, **kwargs): s = encoder(d, **kwargs) if filepath: io_util.write_file(filepath, s) return s @staticmethod - def _from_any_string(s, **kwargs): - d = None + def _from_any_data_string(s, **kwargs): try: d = IODict.from_json(s, **kwargs) + return d except ValueError: - try: - d = IODict.from_toml(s, **kwargs) - except ValueError: - try: - d = IODict.from_xml(s, **kwargs) - except ValueError: - try: - d = IODict.from_yaml(s, **kwargs) - except ValueError: - d = None - return d + pass + try: + d = IODict.from_toml(s, **kwargs) + return d + except ValueError: + pass + try: + d = IODict.from_xml(s, **kwargs) + return d + except ValueError: + pass + try: + d = IODict.from_yaml(s, **kwargs) + return d + except ValueError: + pass @staticmethod def from_json(s, **kwargs): - return IODict._load_and_decode(s, - io_util.decode_json, **kwargs) + return IODict._decode(s, + decoder=io_util.decode_json, **kwargs) @staticmethod def from_toml(s, **kwargs): - return IODict._load_and_decode(s, - io_util.decode_toml, **kwargs) + return IODict._decode(s, + decoder=io_util.decode_toml, **kwargs) @staticmethod def from_xml(s, **kwargs): - return IODict._load_and_decode(s, - io_util.decode_xml, **kwargs) + return IODict._decode(s, + decoder=io_util.decode_xml, **kwargs) - @staticmethod - def from_yaml(s, **kwargs): - return IODict._load_and_decode(s, - io_util.decode_yaml, **kwargs) + @classmethod + def from_yaml(cls, s, **kwargs): + return IODict._decode(s, + decoder=io_util.decode_yaml, **kwargs) def to_json(self, filepath=None, **kwargs): - return IODict._encode_and_save(self, + return IODict._encode(self, encoder=io_util.encode_json, filepath=filepath, **kwargs) def to_toml(self, filepath=None, **kwargs): - return IODict._encode_and_save(self, + return IODict._encode(self, encoder=io_util.encode_toml, filepath=filepath, **kwargs) def to_xml(self, filepath=None, **kwargs): - return IODict._encode_and_save(self, + return IODict._encode(self, encoder=io_util.encode_xml, filepath=filepath, **kwargs) def to_yaml(self, filepath=None, **kwargs): - return IODict._encode_and_save(self, + return IODict._encode(self, encoder=io_util.encode_yaml, filepath=filepath, **kwargs) diff --git a/benedict/utils/io_util.py b/benedict/utils/io_util.py index 30cb422..577c9a4 100644 --- a/benedict/utils/io_util.py +++ b/benedict/utils/io_util.py @@ -51,6 +51,17 @@ def encode_yaml(d, **kwargs): return data +def read_content(s): + # s -> filepath or url or data + if s.startswith('http://') or s.startswith('https://'): + content = read_url(s) + elif os.path.isfile(s): + content = read_file(s) + else: + content = s + return content + + def read_file(filepath): handler = open(filepath, 'r') content = handler.read()