Repository: numpy/numpy
File: doc/source/conf.py (Python)

Code before:
    for part in fullname.split('.'):
        try:
            obj = getattr(obj, part)
        except Exception:
            return None

    # strip decorators, which would resolve to the source of the decorator
    # possibly an upstream bug in getsourcefile, bpo-1764286
    try:
        unwrap = inspect.unwrap
    except AttributeError:
        pass
    else:
        obj = unwrap(obj)

    fn = None
    lineno = None

    if isinstance(obj, type):
        # Make a poor effort at linking C extension types
        if obj.__module__ == 'numpy':
            fn = _get_c_source_file(obj)

        # This can be removed when removing the decorator set_module. Fix issue #28629
        if hasattr(obj, '_module_source'):
            obj = copy(obj)
            obj.__module__ = obj._module_source

    if fn is None:
        try:
            fn = inspect.getsourcefile(obj)
        except Exception:
            fn = None
        if not fn:
            return None

        # Ignore re-exports as their source files are not within the numpy repo
        module = inspect.getmodule(obj)
        if module is not None and not module.__name__.startswith("numpy"):
            return None

        try:
            source, lineno = inspect.getsourcelines(obj)
        except Exception:
            lineno = None

        fn = relpath(fn, start=dirname(numpy.__file__))

    if lineno:
        linespec = "#L%d-L%d" % (lineno, lineno + len(source) - 1)
    else:

Review comment (suggestion):
this is a no-op:

```pycon
>>> import copy
>>> class A: ...
... 
>>> copy.copy(A) is A
True
```

and it's the same story with `copy.deepcopy`:

```pycon
>>> copy.deepcopy(A) is A
True
```

Code after:
        try:
            obj = getattr(obj, part)
        except Exception:
            return None

    # strip decorators, which would resolve to the source of the decorator
    # possibly an upstream bug in getsourcefile, bpo-1764286
    try:
        unwrap = inspect.unwrap
    except AttributeError:
        pass
    else:
        obj = unwrap(obj)

    fn = None
    lineno = None

    if isinstance(obj, type):
        # Make a poor effort at linking C extension types
        if obj.__module__ == 'numpy':
            fn = _get_c_source_file(obj)

        # This can be removed when removing the decorator set_module. Fix issue #28629
        if hasattr(obj, '_module_source'):
            obj.__module__, obj._module_source = obj._module_source, obj.__module__

    if fn is None:
        try:
            fn = inspect.getsourcefile(obj)
        except Exception:
            fn = None
        if not fn:
            return None

        # Ignore re-exports as their source files are not within the numpy repo
        module = inspect.getmodule(obj)
        if module is not None and not module.__name__.startswith("numpy"):
            return None

        try:
            source, lineno = inspect.getsourcelines(obj)
        except Exception:
            lineno = None

        fn = relpath(fn, start=dirname(numpy.__file__))

    if lineno:
        linespec = "#L%d-L%d" % (lineno, lineno + len(source) - 1)
    else:
        linespec = ""