diff --git a/CHANGELOG b/CHANGELOG index 8e9f090..7ec2de2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ jello changelog +20210626 v1.4.4 +- Rename internal variables so they don't collide with user defined names +- Clean up user runtime environment of unused varialbles + 20210623 v1.4.3 - Update html formatting tests to only run if Pygments v2.9.0 is installed - Fix typo in man page diff --git a/jello/__init__.py b/jello/__init__.py index 604688e..4fe59f1 100644 --- a/jello/__init__.py +++ b/jello/__init__.py @@ -1,7 +1,7 @@ """jello - query JSON at the command line with python syntax""" -__version__ = '1.4.3' +__version__ = '1.4.4' AUTHOR = 'Kelly Brazil' WEBSITE = 'https://github.com/kellyjonbrazil/jello' COPYRIGHT = '© 2020-2021 Kelly Brazil' diff --git a/jello/lib.py b/jello/lib.py index dfe27ad..b562bb1 100644 --- a/jello/lib.py +++ b/jello/lib.py @@ -312,82 +312,102 @@ def load_json(data): return json_dict -def pyquery(data, query): - """Sets options and runs the user's query""" - output = None +def pyquery(_θ_data, _θ_query): + """Sets options and runs the user's query. This function uses odd variable names so they don't + collide with user defined names.""" + _θ_output = None # read data into '_' variable # if data is a list of dictionaries, then need to iterate through and convert all dictionaries to DotMap - if isinstance(data, list): + if isinstance(_θ_data, list): _ = [DotMap(i, _dynamic=False, _prevent_method_masking=True) if isinstance(i, dict) - else i for i in data] + else i for i in _θ_data] - elif isinstance(data, dict): - _ = DotMap(data, _dynamic=False, _prevent_method_masking=True) + elif isinstance(_θ_data, dict): + _ = DotMap(_θ_data, _dynamic=False, _prevent_method_masking=True) else: - _ = data + _ = _θ_data + + del _θ_data # read initialization file to set colors, options, and user-defined functions - jelloconf = '' - conf_file = '' + _θ_jelloconf = '' + _θ_conf_file = '' if opts.initialize: if sys.platform.startswith('win32'): - conf_file = os.path.join(os.environ['APPDATA'], '.jelloconf.py') + _θ_conf_file = os.path.join(os.environ['APPDATA'], '.jelloconf.py') else: - conf_file = os.path.join(os.environ["HOME"], '.jelloconf.py') + _θ_conf_file = os.path.join(os.environ["HOME"], '.jelloconf.py') try: - with open(conf_file, 'r') as f: - jelloconf = f.read() + with open(_θ_conf_file, 'r') as _θ_f: + _θ_jelloconf = _θ_f.read() + del _θ_f except FileNotFoundError: - raise FileNotFoundError(f'-i used and initialization file not found: {conf_file}') + raise FileNotFoundError(f'-i used and initialization file not found: {_θ_conf_file}') - warn_options = False - warn_colors = False + _θ_warn_options = False + _θ_warn_colors = False - i_block = ast.parse(jelloconf, mode='exec') - exec(compile(i_block, '', mode='exec')) + _θ_i_block = ast.parse(_θ_jelloconf, mode='exec') + exec(compile(_θ_i_block, '', mode='exec')) - for option in [opts.compact, opts.raw, opts.lines, opts.nulls, opts.mono, opts.schema, opts.types]: - if not isinstance(option, bool) and option is not None: + for _θ_option in [opts.compact, opts.raw, opts.lines, opts.nulls, opts.mono, opts.schema, opts.types]: + if not isinstance(_θ_option, bool) and _θ_option is not None: opts.compact = opts.raw = opts.lines = opts.nulls = opts.mono = opts.schema = opts.types = False - warn_options = True + _θ_warn_options = True - for color_config in [opts.keyname_color, opts.keyword_color, opts.number_color, opts.string_color]: - valid_colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'gray', 'brightblack', 'brightred', - 'brightgreen', 'brightyellow', 'brightblue', 'brightmagenta', 'brightcyan', 'white'] + for _θ_color_config in [opts.keyname_color, opts.keyword_color, opts.number_color, opts.string_color]: + _θ_valid_colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'gray', 'brightblack', + 'brightred', 'brightgreen', 'brightyellow', 'brightblue', 'brightmagenta', 'brightcyan', + 'white'] - if color_config not in valid_colors and color_config is not None: + if _θ_color_config not in _θ_valid_colors and _θ_color_config is not None: opts.keyname_color = opts.keyword_color = opts.number_color = opts.string_color = None - warn_colors = True + _θ_warn_colors = True + + if _θ_warn_options: + print(f'Jello: Warning: Options must be set to True or False in {_θ_conf_file}\n Unsetting all options.\n', file=sys.stderr) - if warn_options: - print(f'Jello: Warning: Options must be set to True or False in {conf_file}\n Unsetting all options.\n', file=sys.stderr) + if _θ_warn_colors: + _θ_valid_colors_string = ', '.join(_θ_valid_colors) + print(f'Jello: Warning: Colors must be set to one of: {_θ_valid_colors_string} in {_θ_conf_file}\n Unsetting all colors.\n', file=sys.stderr) - if warn_colors: - valid_colors_string = ', '.join(valid_colors) - print(f'Jello: Warning: Colors must be set to one of: {valid_colors_string} in {conf_file}\n Unsetting all colors.\n', file=sys.stderr) + # clean up variables + del _θ_color_config + del _θ_conf_file + del _θ_i_block + del _θ_jelloconf + del _θ_option + del _θ_valid_colors + del _θ_warn_colors + del _θ_warn_options # run the query - block = ast.parse(query, mode='exec') - last = ast.Expression(block.body.pop().value) # assumes last node is an expression - exec(compile(block, '', mode='exec')) - output = eval(compile(last, '', mode='eval')) + _θ_block = ast.parse(_θ_query, mode='exec') + del _θ_query + _θ_last = ast.Expression(_θ_block.body.pop().value) # assumes last node is an expression + + exec(compile(_θ_block, '', mode='exec')) + del _θ_block + + _θ_output = eval(compile(_θ_last, '', mode='eval')) + del _θ_last # convert output back to normal dict - if isinstance(output, list): - output = [i.toDict() if isinstance(i, DotMap) else i for i in output] + if isinstance(_θ_output, list): + _θ_output = [i.toDict() if isinstance(i, DotMap) else i for i in _θ_output] - elif isinstance(output, DotMap): - output = output.toDict() + elif isinstance(_θ_output, DotMap): + _θ_output = _θ_output.toDict() # if DotMap returns a bound function then we know it was a reserved attribute name - if hasattr(output, '__self__'): + if hasattr(_θ_output, '__self__'): raise ValueError('Reserved key name. Use bracket notation to access this key.') - return output + return _θ_output if __name__ == '__main__': diff --git a/setup.py b/setup.py index 20835a1..c1ead8f 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name='jello', - version='1.4.3', + version='1.4.4', author='Kelly Brazil', author_email='kellyjonbrazil@gmail.com', description='Filter JSON and JSON Lines data with Python syntax.',