From 288b9be012a034628d646877714be2e2934aab77 Mon Sep 17 00:00:00 2001 From: Kevin Kress Date: Sun, 23 Dec 2012 22:27:52 -0800 Subject: [PATCH] add @export syntax for handling __all__ This adds a decorator that checks for __all__ and then exports decorated functions and classes to it. --- r2/r2/lib/export.py | 54 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 r2/r2/lib/export.py diff --git a/r2/r2/lib/export.py b/r2/r2/lib/export.py new file mode 100644 index 000000000..6e6b3e0f8 --- /dev/null +++ b/r2/r2/lib/export.py @@ -0,0 +1,54 @@ +# The contents of this file are subject to the Common Public Attribution +# License Version 1.0. (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://code.reddit.com/LICENSE. The License is based on the Mozilla Public +# License Version 1.1, but Sections 14 and 15 have been added to cover use of +# software over a computer network and provide for limited attribution for the +# Original Developer. In addition, Exhibit A has been modified to be consistent +# with Exhibit B. +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +# the specific language governing rights and limitations under the License. +# +# The Original Code is reddit. +# +# The Original Developer is the Initial Developer. The Initial Developer of +# the Original Code is reddit Inc. +# +# All portions of the code written by reddit are Copyright (c) 2006-2012 reddit +# Inc. All Rights Reserved. +############################################################################### + +import sys + +__all__ = ["export", "ExportError"] + + +class ExportError(Exception): + def __init__(self, module): + msg = "Missing __all__ declaration in module %s. " \ + "@export cannot be used without declaring __all__ " \ + "in that module." % (module) + Exception.__init__(self, msg) + + +def export(exported_entity): + """Use a decorator to avoid retyping function/class names. + + * Based on an idea by Duncan Booth: + http://groups.google.com/group/comp.lang.python/msg/11cbb03e09611b8a + * Improved via a suggestion by Dave Angel: + http://groups.google.com/group/comp.lang.python/msg/3d400fb22d8a42e1 + * Copied from Stack Overflow + http://stackoverflow.com/questions/6206089/is-it-a-good-practice-to-add-names-to-all-using-a-decorator + """ + all_var = sys.modules[exported_entity.__module__].__dict__.get('__all__') + if all_var is None: + raise ExportError(exported_entity.__module__) + if exported_entity.__name__ not in all_var: # Prevent duplicates if run from an IDE. + all_var.append(exported_entity.__name__) + return exported_entity + +export(export) # Emulate decorating ourself +