-
-
Notifications
You must be signed in to change notification settings - Fork 32k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extracted json saving and loading #10216
Conversation
homeassistant/util/__init__.py
Outdated
""" | ||
try: | ||
with open(filename, 'w', encoding='utf-8') as fdesc: | ||
fdesc.write(json.dumps(config, sort_keys=True, indent=4)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should json dump to a string before opening the file. That way, when dumping fails we don't truncate the file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point!
homeassistant/util/__init__.py
Outdated
try: | ||
with open(filename, 'w', encoding='utf-8') as fdesc: | ||
fdesc.write(json.dumps(config, sort_keys=True, indent=4)) | ||
return True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent return .
homeassistant/util/__init__.py
Outdated
@@ -116,6 +121,38 @@ def get_random_string(length=10): | |||
return ''.join(generator.choice(source_chars) for _ in range(length)) | |||
|
|||
|
|||
def load_json(filename: str) -> Union[List, Dict]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's move these files to their own package util.json
homeassistant/util/__init__.py
Outdated
except FileNotFoundError: | ||
_LOGGER.debug('JSON file not found: %s', filename) | ||
except ValueError: | ||
_LOGGER.warning('Could not parse JSON content: %s', filename) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This error is pretty bad, we should probably just blow up?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right. I didn't want to change the behavior much from what was currently in place/use.
I'll raise a HomeAsssistantError, analogous to load_yaml, instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This means that we do no longer support empty files?
homeassistant/util/__init__.py
Outdated
except ValueError: | ||
_LOGGER.warning('Could not parse JSON content: %s', filename) | ||
except OSError as error: | ||
_LOGGER.warning('JSON file reading failed: %s (%s)', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This error is pretty bad, we should probably just blow up?
homeassistant/util/__init__.py
Outdated
with open(filename, 'w', encoding='utf-8') as fdesc: | ||
fdesc.write(json.dumps(config, sort_keys=True, indent=4)) | ||
return True | ||
except OSError as error: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, should we blow up to make sure that both user and code knows it did not manage to save anything.
This is a great initiative! Especially |
homeassistant/util/json.py
Outdated
""" | ||
try: | ||
with open(filename, 'w', encoding='utf-8') as fdesc: | ||
data = json.dumps(config, sort_keys=True, indent=4) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should do this before opening the file, otherwise the file has already been truncated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok to merge when last comment addressed 🐬 🌮 thanks!
Description:
Many components use json files to store custom configuration data.
All implements their own very basic code for loading and saving dicts as JSON files (
with open(filename) as f: json.loads(f)
). Some do error checking (checking if file exists or not), some do not. Some catch relevant exceptions, some do not.It is obvious that in most places, the exact same logic is taking place, and in many places the same code is duplicated (a 20-line function
config_from_file(filename, config=None)
seems to be copied around a lot).This PR provides basic functionality for loading and saving dicts as JSON (
load_json
,save_json
, analogous withload_yaml
) in core.Benefits: Less code duplication, hopefully somewhat better error handling, better reporting in the logs, and easier testing/mocking.
The PR only contain changes in one component (
media_player/plex.py
) to useload_json
andsave_json
, but at least the places mentioned in #10269 could possibly also benefit from this change.Related issue (if applicable): fixes #
Pull request in home-assistant.github.io with documentation (if applicable): home-assistant/home-assistant.github.io#<home-assistant.github.io PR number goes here>
Example entry for
configuration.yaml
(if applicable):Checklist:
If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
tox
run successfully. Your PR cannot be merged unless tests passREQUIREMENTS
variable (example).requirements_all.txt
by runningscript/gen_requirements_all.py
..coveragerc
.If the code does not interact with devices:
tox
run successfully. Your PR cannot be merged unless tests pass