Skip to content

Instantly share code, notes, and snippets.

@gtors
Created March 3, 2020 19:42
Show Gist options
  • Select an option

  • Save gtors/fcf6af1484b8dd629b69b049e2e3ed17 to your computer and use it in GitHub Desktop.

Select an option

Save gtors/fcf6af1484b8dd629b69b049e2e3ed17 to your computer and use it in GitHub Desktop.
Auto generate __all__ variable
#!/usr/bin/env python3
import sys
# NOTE: redbaron have no full support of python3.7, so construction such as `foo = {**bar}` may cause crash
from redbaron import RedBaron
def generate_all_variable(file_name: str):
with open(file_name, 'r+') as src:
rb = RedBaron(src.read())
_all_ = None
public_items = []
last_import_idx = None
for idx, node in enumerate(rb):
# If __all__ already exists, we will rewrite it
if node.type == 'assignment' and str(node.name) == '__all__':
_all_ = node
# Memorizing the last import position to insert __all__, if it's not exists yet
elif node.type in ('import', 'from_import'):
last_import_idx = idx + 1
# Collect all public classes/functions names
elif node.type in ('class', 'def') and not node.name.startswith('_'):
public_items.append(node.name)
if public_items:
new_all_ = f'__all__ = {tuple(sorted(public_items))}'
if _all_ is not None:
all_idx = rb.index(_all_)
rb.remove(_all_)
rb.insert(all_idx, new_all_)
else:
rb.insert(last_import_idx or 0, new_all_)
rb.insert(last_import_idx or 0, '\n')
src.seek(0)
src.truncate()
src.write(rb.dumps())
if __name__ == '__main__':
# The first argument is required and must be an absolute path to *.py file
generate_all_variable(sys.argv[1])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment