Determine the URL corresponding to Python object
(domain, info)
| 439 | |
| 440 | |
| 441 | def linkcode_resolve(domain, info): |
| 442 | """ |
| 443 | Determine the URL corresponding to Python object |
| 444 | """ |
| 445 | if domain != 'py': |
| 446 | return None |
| 447 | |
| 448 | modname = info['module'] |
| 449 | fullname = info['fullname'] |
| 450 | |
| 451 | submod = sys.modules.get(modname) |
| 452 | if submod is None: |
| 453 | return None |
| 454 | |
| 455 | obj = submod |
| 456 | for part in fullname.split('.'): |
| 457 | try: |
| 458 | obj = getattr(obj, part) |
| 459 | except Exception: |
| 460 | return None |
| 461 | |
| 462 | # strip decorators, which would resolve to the source of the decorator |
| 463 | # possibly an upstream bug in getsourcefile, bpo-1764286 |
| 464 | try: |
| 465 | unwrap = inspect.unwrap |
| 466 | except AttributeError: |
| 467 | pass |
| 468 | else: |
| 469 | obj = unwrap(obj) |
| 470 | |
| 471 | fn = None |
| 472 | lineno = None |
| 473 | |
| 474 | # Make a poor effort at linking C extension types |
| 475 | if isinstance(obj, type) and obj.__module__ == 'numpy': |
| 476 | fn = _get_c_source_file(obj) |
| 477 | |
| 478 | if fn is None: |
| 479 | try: |
| 480 | fn = inspect.getsourcefile(obj) |
| 481 | except Exception: |
| 482 | fn = None |
| 483 | if not fn: |
| 484 | return None |
| 485 | |
| 486 | # Ignore re-exports as their source files are not within the numpy repo |
| 487 | module = inspect.getmodule(obj) |
| 488 | if module is not None and not module.__name__.startswith("numpy"): |
| 489 | return None |
| 490 | |
| 491 | try: |
| 492 | source, lineno = inspect.getsourcelines(obj) |
| 493 | except Exception: |
| 494 | lineno = None |
| 495 | |
| 496 | fn = relpath(fn, start=dirname(numpy.__file__)) |
| 497 | |
| 498 | if lineno: |
nothing calls this directly
no test coverage detected