| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -135,12 +135,8 @@ class XMLExternalCallee extends XMLCallee { | |||
| 135 | 135 | ||
| 136 | 136 | Builtin getACallee() { | |
| 137 | 137 | exists(Builtin mod | | |
| 138 | - not this.get_module_data() = "None" and | ||
| 139 | 138 | mod.isModule() and | |
| 140 | 139 | mod.getName() = this.get_module_data() | |
| 141 | - or | ||
| 142 | - this.get_module_data() = "None" and | ||
| 143 | - mod = Builtin::builtinModule() | ||
| 144 | 140 | | | |
| 145 | 141 | result = traverse_qualname(mod, this.get_qualname_data()) | |
| 146 | 142 | ) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -95,6 +95,41 @@ class Callee: | |||
| 95 | 95 | ||
| 96 | 96 | ||
| 97 | 97 | BUILTIN_FUNCTION_OR_METHOD = type(print) | |
| 98 | + METHOD_DESCRIPTOR_TYPE = type(dict.get) | ||
| 99 | + | ||
| 100 | + | ||
| 101 | + _unknown_module_fixup_cache = dict() | ||
| 102 | + | ||
| 103 | + | ||
| 104 | + def _unkown_module_fixup(func): | ||
| 105 | + # TODO: Doesn't work for everything (for example: `OrderedDict.fromkeys`, `object.__new__`) | ||
| 106 | + | ||
| 107 | + module = func.__module__ | ||
| 108 | + qualname = func.__qualname__ | ||
| 109 | + cls_name, method_name = qualname.split(".") | ||
| 110 | + | ||
| 111 | + key = (module, qualname) | ||
| 112 | + if key in _unknown_module_fixup_cache: | ||
| 113 | + return _unknown_module_fixup_cache[key] | ||
| 114 | + | ||
| 115 | + matching_classes = list() | ||
| 116 | + for klass in object.__subclasses__(): | ||
| 117 | + # type(dict.get) == METHOD_DESCRIPTOR_TYPE | ||
| 118 | + # type(dict.__new__) == BUILTIN_FUNCTION_OR_METHOD | ||
| 119 | + if klass.__qualname__ == cls_name and type( | ||
| 120 | + getattr(klass, method_name, None) | ||
| 121 | + ) in [BUILTIN_FUNCTION_OR_METHOD, METHOD_DESCRIPTOR_TYPE]: | ||
| 122 | + matching_classes.append(klass) | ||
| 123 | + | ||
| 124 | + if len(matching_classes) == 1: | ||
| 125 | + klass = matching_classes[0] | ||
| 126 | + ret = klass.__module__ | ||
| 127 | + else: | ||
| 128 | + if DEBUG: | ||
| 129 | + LOGGER.debug(f"Found more than one matching class for {module} {qualname}") | ||
| 130 | + ret = None | ||
| 131 | + _unknown_module_fixup_cache[key] = ret | ||
| 132 | + return ret | ||
| 98 | 133 | ||
| 99 | 134 | ||
| 100 | 135 | @better_compare_for_dataclass | |
@@ -109,9 +144,19 @@ class ExternalCallee(Callee): | |||
| 109 | 144 | ||
| 110 | 145 | @classmethod | |
| 111 | 146 | def from_arg(cls, func): | |
| 147 | + # builtin bound methods seems to always return `None` for __module__, but we | ||
| 148 | + # might be able to recover the lost information by looking through all classes. | ||
| 149 | + # For example, `dict().get.__module__ is None` and `dict().get.__qualname__ == | ||
| 150 | + # "dict.get"` | ||
| 151 | + | ||
| 152 | + module = func.__module__ | ||
| 153 | + qualname = func.__qualname__ | ||
| 154 | + if module is None and qualname.count(".") == 1: | ||
| 155 | + module = _unkown_module_fixup(func) | ||
| 156 | + | ||
| 112 | 157 | return cls( | |
| 113 | - module=func.__module__, | ||
| 114 | - qualname=func.__qualname__, | ||
| 158 | + module=module, | ||
| 159 | + qualname=qualname, | ||
| 115 | 160 | is_builtin=type(func) == BUILTIN_FUNCTION_OR_METHOD, | |
| 116 | 161 | ) | |
| 117 | 162 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,3 @@ | |||
| 1 | + d = dict() | ||
| 2 | + | ||
| 3 | + d.get("foo") or d.get("bar") | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,4 @@ | |||
| 1 | + import socket | ||
| 2 | + | ||
| 3 | + sock = socket.socket() | ||
| 4 | + print(sock.getsockname()) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,4 @@ | |||
| 1 | + import io | ||
| 2 | + | ||
| 3 | + # the `io.open` is just an alias for `_io.open`, but we record the external callee as `io.open` :| | ||
| 4 | + io.open("foo") | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments