26    \ingroup Pythonizations 
   27    Decorator that allows to pythonize C++ classes. To pythonize means to add 
   28    some extra behaviour to a C++ class that is used from Python via PyROOT, 
   29    so that such a class can be used in an easier / more "pythonic" way. 
   30    When a pythonization is registered with this decorator, the injection of 
   31    the new behaviour in the C++ class is done immediately, if the class has 
   32    already been used from the application, or lazily, i.e. only when the class 
   33    is first accessed from the application. 
   36        class_name (string/iterable[string]): specifies either a single string or 
   37            multiple strings, where each string can be either (i) the name of a 
   38            C++ class to be pythonized, or (ii) a prefix to match all classes 
   39            whose name starts with that prefix. 
   40        ns (string): namespace of the classes to be pythonized. Default is the 
   41            global namespace (`::`). 
   42        is_prefix (boolean): if True, `class_name` contains one or multiple 
   43            prefixes, each prefix potentially matching multiple classes. 
   45            These are examples of prefixes and namespace and what they match: 
   46            - class_name="", ns="::" : all classes in the global namespace. 
   47            - class_name="C", ns="::" : all classes in the global namespace 
   48              whose name starts with "C" 
   49            - class_name="", ns="NS1::NS2" : all classes in namespace "NS1::NS2" 
   50            - class_name="C", ns="NS1::NS2" : all classes in namespace 
   51              "NS1::NS2" whose name starts with "C" 
   54        function: function that receives the user-defined function and 
   76            return class_name 
in target
 
   80        The real decorator. Accepts a user-provided function and decorates it. 
   81        An inner function - a wrapper of the user function - is registered in 
   82        cppyy as a pythonizor. 
   85            user_pythonizor (function): user-provided function to be decorated. 
   86                It implements some pythonization. It can accept two parameters: 
   87                the class to be pythonized, i.e. the Python proxy of the class 
   88                in which new behaviour can be injected, and optionally the name 
   89                of that class (can be used e.g. to do some more complex 
   93            function: the user function, after being registered as a 
  106            Wrapper function with the parameters that cppyy requires for a 
  107            pythonizor function (class proxy and class name). It invokes the 
  108            user function only if the current class - a candidate for being 
  109            pythonized - matches the `target` argument of the decorator. 
  112                klass (class type): cppyy proxy of the class that is the 
  113                    current candidate to be pythonized. 
  114                name (string): name of the class that is the current candidate 
  121            pythonize_generic(klass, fqn)
 
  124                _invoke(user_pythonizor, npars, klass, fqn)
 
  134        return user_pythonizor
 
  136    return pythonization_impl
 
  144    Helper function to check the type of the `class name` argument specified by 
  145    the user in a @pythonization decorator. 
  148        target (string/iterable[string]): class name(s)/prefix(es). 
  151        list[string]: class name(s)/prefix(es) in `target`, with no repetitions. 
  163                    'Invalid type of "target" argument in @pythonization: must be string or iterable of strings' 
  166        target = list(set(target))
 
  173    Checks that a given target of a pythonizor does not specify a namespace 
  174    (only the class name / prefix of a class name should be present). 
  177        target (string): class name/prefix. 
  182            'Invalid value of "class_name" argument in ' 
  183            '@pythonization: namespace definition found ("{}"). ' 
  184            'Please use the "ns" parameter to specify the ' 
  185            "namespace".
format(target)
 
  191    Checks the number of parameters of the `f` function. 
  194        f (function): user pythonizor function. 
  197        int: number of positional parameters of `f`. 
  200    if npars == 0 
or npars > 2:
 
  202            "Pythonizor function {} has a wrong number of " 
  203            "parameters ({}). Allowed parameters are the class to " 
  210def _invoke(user_pythonizor, npars, klass, fqn):
 
  212    Invokes the given user pythonizor function with the right arguments. 
  215        user_pythonizor (function): user pythonizor function. 
  216        npars (int): number of parameters of the user pythonizor function. 
  217        klass (class type): cppyy proxy of the class to be pythonized. 
  218        fqn (string): fully-qualified name of the class to be pythonized. 
  227        print(
"Error pythonizing class {}:".
format(fqn))
 
  236    Finds already instantiated classes in namespace `ns` that pass the filter 
  237    of `passes_filter`. Every matching class is pythonized with the 
  238    `user_pythonizor` function. 
  239    This makes sure a pythonizor is also applied to classes that have already 
  240    been used at the time the pythonizor is registered. 
  243        ns (string): namespace of the class names of prefixes in `targets`. 
  244        passes_filter (function): function that determines if a given class 
  245            is the target of `user_pythonizor`. 
  246        user_pythonizor (function): user pythonizor function. 
  247        npars (int): number of parameters of the user pythonizor function. 
  270        if hasattr(instantiation, 
"__cpp_name__"):
 
  273        if hasattr(instantiation, 
"__name__"):
 
  277            f
"The template instantiation '{instantiation}' cannot be properly pythonized. Please report this as a bug." 
  280    ns_vars = vars(ns_obj)
 
  282        if str(var_value).
startswith(
"<class cppyy.gbl."):
 
  286        if str(var_value).
startswith(
"<cppyy.Template"):
 
  291            instantiations = 
getattr(var_value, 
"_instantiations", {})
 
  296                if instance 
not in ns_vars:
 
  297                    instance_name = var_name + 
"<" + 
",".join(map(get_class_name, args)) + 
">" 
  303    Finds and returns the proxy object of the `ns` namespace, if it has already 
  307        ns (string): a namespace. 
  310        namespace proxy object, if the namespace has already been accessed, 
  317    ns_obj = gbl_namespace
 
  321        ns_vars = vars(ns_obj)
 
  322        if ns 
not in ns_vars:
 
  331    Registers the ROOT pythonizations with cppyy for lazy injection. 
  334    exclude = [
"_rdf_utils", 
"_rdf_pyz", 
"_rdf_conversion_maps"]
 
  336        if module_name 
not in exclude: