Python Export Decorator
Personally, I'd prefer to use @export() or @export(globals()), rather than manually perform the @ sugar.
I don't like using __globals__, even if it is writeable.
Honestly, I think the cleanest solution would be to abuse lists, and use a closure.
I do however agree that inheriting from Exception, is the best parent to inherit from.


And so I'd personally use something more like:

class ExportError(Exception):
    """Exception if redundant names attempted exporting"""

def build_export(__all__=None):
    if __all__ is None:
        __all__ = []
    def export(obj):
        name = obj if isinstance(obj, str) else obj.__name__
        if name in __all__:
            raise ExportError(f'{name} already exported')
        __all__.append(name)
        return obj
    return __all__, export


__all__, export = build_export()


@export
class Foo:
    pass


@export
def bar():
    pass