[pycharm] ENH: More robust type renderer match routine, and fix for pandas upcoming impactful changes

Merge-request: IJ-MR-174845
Merged-by: Egor Eliseev <Egor.Eliseev@jetbrains.com>

GitOrigin-RevId: 002967c14cf75b8d0298dd9123a244c3d969b55c
This commit is contained in:
dangreb
2025-09-08 16:03:34 +00:00
committed by intellij-monorepo-bot
parent f9bd233810
commit d5035cdae9
@@ -1,8 +1,41 @@
# Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
import inspect
from _pydevd_bundle import pydevd_utils
try:
# IDE's own module importer (handles namespace packages, zip, etc.)
from _pydevd_bundle import pydevd_import_class as _pydevd_import_class
except Exception:
_pydevd_import_class = None
def _resolve_type(path):
"""Resolve 'pkg.mod.Class' -> class object, or None."""
if not path:
return None
# Prefer pydevd's own importer so future understandings
# over runtime module imports may propagate seamlessly
if _pydevd_import_class is not None:
for attr in ('import_name', 'ImportName'):
fn = getattr(_pydevd_import_class, attr, None)
if callable(fn):
try:
return fn(path)
except:
pass
return None
def _by_type_entities(cls, renderers_dict):
"""Resolve names into types for entity-bound type matching criteria"""
for render in [render for renders in renderers_dict.values() for render in renders]:
try:
for name_type in ('type_canonical_import_path','type_qualified_name'):
target = _resolve_type(getattr(render, name_type, None))
if cls is target:
return render
except:
pass
return None
class TypeRenderersConstants:
new_line = "@_@NEW_LINE_CHAR@_@"
@@ -15,7 +48,8 @@ def try_get_type_renderer_for_var(var, renderers_dict):
cls_name = cls.__name__
renderers_for_name = renderers_dict.get(cls_name)
if renderers_for_name is None:
return None
# by class type entities
return _by_type_entities(cls, renderers_dict)
module_name = cls.__module__
qualified_name = module_name + "." + cls_name
@@ -37,12 +71,8 @@ def try_get_type_renderer_for_var(var, renderers_dict):
for render in renderers_for_name:
if render.type_src_file == src_file:
return render
return None
# by qualified name
for render in renderers_for_name:
if render.type_qualified_name == qualified_name:
return render
# by class type entities
return _by_type_entities(cls, renderers_dict)
# by module root and class name
# (if module contains only one class with the same name)
@@ -52,6 +82,10 @@ def try_get_type_renderer_for_var(var, renderers_dict):
renderer_module_root = render.type_canonical_import_path.split(".")[0]
if renderer_module_root == module_root:
return render
# by qualified name
return _by_type_entities(cls, renderers_dict)
except:
pass