|
| 1 | +# coding=utf-8 |
| 2 | +""" |
| 3 | +.NET (CLR) specific functions |
| 4 | +""" |
| 5 | +__author__ = 'Ilya.Kazakevich' |
| 6 | + |
| 7 | + |
| 8 | +def get_namespace_by_name(object_name): |
| 9 | + """ |
| 10 | + Gets namespace for full object name. Sometimes last element of name is module while it may be class. |
| 11 | + For System.Console returns System, for System.Web returns System.Web. |
| 12 | + Be sure all required assemblies are loaded (i.e. clr.AddRef.. is called) |
| 13 | + :param object_name: name to parse |
| 14 | + :return: namespace |
| 15 | + """ |
| 16 | + (imported_object, object_name) = _import_first(object_name) |
| 17 | + parts = object_name.partition(".") |
| 18 | + first_part = parts[0] |
| 19 | + remain_part = parts[2] |
| 20 | + |
| 21 | + while remain_part and type(_get_attr_by_name(imported_object, remain_part)) is type: # While we are in class |
| 22 | + remain_part = remain_part.rpartition(".")[0] |
| 23 | + |
| 24 | + if remain_part: |
| 25 | + return first_part + "." + remain_part |
| 26 | + else: |
| 27 | + return first_part |
| 28 | + |
| 29 | + |
| 30 | +def _import_first(object_name): |
| 31 | + """ |
| 32 | + Some times we can not import module directly. For example, Some.Class.InnerClass could not be imported: you need to import "Some.Class" |
| 33 | + or even "Some" instead. This function tries to find part of name that could be loaded |
| 34 | +
|
| 35 | + :param object_name: name in dotted notation like "Some.Function.Here" |
| 36 | + :return: (imported_object, object_name): tuple with object and its name |
| 37 | + """ |
| 38 | + while object_name: |
| 39 | + try: |
| 40 | + return (__import__(object_name, globals=[], locals=[], fromlist=[]), object_name) |
| 41 | + except ImportError: |
| 42 | + object_name = object_name.rpartition(".")[0] # Remove rightest part |
| 43 | + raise Exception("No module name found in name " + object_name) |
| 44 | + |
| 45 | + |
| 46 | +def _get_attr_by_name(obj, name): |
| 47 | + """ |
| 48 | + Accepts chain of attributes in dot notation like "some.property.name" and gets them on object |
| 49 | + :param obj: object to introspec |
| 50 | + :param name: attribute name |
| 51 | + :return attribute |
| 52 | +
|
| 53 | + >>> str(_get_attr_by_name("A", "__class__.__class__")) |
| 54 | + "<type 'type'>" |
| 55 | +
|
| 56 | + >>> str(_get_attr_by_name("A", "__class__.__len__.__class__")) |
| 57 | + "<type 'method_descriptor'>" |
| 58 | + """ |
| 59 | + result = obj |
| 60 | + parts = name.split('.') |
| 61 | + for part in parts: |
| 62 | + result = getattr(result, part) |
| 63 | + return result |
0 commit comments