Build an __init__ decorator that triggers ClassManager events.
(class_, class_manager, original_init)
| 702 | |
| 703 | |
| 704 | def _generate_init(class_, class_manager, original_init): |
| 705 | """Build an __init__ decorator that triggers ClassManager events.""" |
| 706 | |
| 707 | # TODO: we should use the ClassManager's notion of the |
| 708 | # original '__init__' method, once ClassManager is fixed |
| 709 | # to always reference that. |
| 710 | |
| 711 | if original_init is None: |
| 712 | original_init = class_.__init__ |
| 713 | |
| 714 | # Go through some effort here and don't change the user's __init__ |
| 715 | # calling signature, including the unlikely case that it has |
| 716 | # a return value. |
| 717 | # FIXME: need to juggle local names to avoid constructor argument |
| 718 | # clashes. |
| 719 | func_body = """\ |
| 720 | def __init__(%(apply_pos)s): |
| 721 | new_state = class_manager._new_state_if_none(%(self_arg)s) |
| 722 | if new_state: |
| 723 | return new_state._initialize_instance(%(apply_kw)s) |
| 724 | else: |
| 725 | return original_init(%(apply_kw)s) |
| 726 | """ |
| 727 | func_vars = util.format_argspec_init(original_init, grouped=False) |
| 728 | func_text = func_body % func_vars |
| 729 | |
| 730 | func_defaults = getattr(original_init, "__defaults__", None) |
| 731 | func_kw_defaults = getattr(original_init, "__kwdefaults__", None) |
| 732 | |
| 733 | env = locals().copy() |
| 734 | env["__name__"] = __name__ |
| 735 | exec(func_text, env) |
| 736 | __init__ = env["__init__"] |
| 737 | __init__.__doc__ = original_init.__doc__ |
| 738 | __init__._sa_original_init = original_init |
| 739 | |
| 740 | if func_defaults: |
| 741 | __init__.__defaults__ = func_defaults |
| 742 | if func_kw_defaults: |
| 743 | __init__.__kwdefaults__ = func_kw_defaults |
| 744 | |
| 745 | return __init__ |
no test coverage detected