Skip to content

warnings.deprecated doesn't work well with pydoc #128772

Closed
@Viicos

Description

@Viicos

Bug report

Bug description:

Steps to reproduce:

  • Create a module (testmodule.py):
    from warnings import deprecated
    
    @deprecated("Test")
    class A: pass
  • In the Python shell, run:
    import testmodule
    help(testmodule) 

This will raise a TypeError:

  File "/fakepath/uv/python/cpython-3.13.1-linux-x86_64-gnu/lib/python3.13/pydoc.py", line 245, in parentname
    return object.__module__ + '.' + name
           ~~~~~~~~~~~~~~~~~~^~~~~
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

warnings.deprecated is defining custom __new__ and __init_subclass__ methods:

cpython/Lib/warnings.py

Lines 588 to 615 in 6e1e780

original_new = arg.__new__
@functools.wraps(original_new)
def __new__(cls, *args, **kwargs):
if cls is arg:
warn(msg, category=category, stacklevel=stacklevel + 1)
if original_new is not object.__new__:
return original_new(cls, *args, **kwargs)
# Mirrors a similar check in object.__new__.
elif cls.__init__ is object.__init__ and (args or kwargs):
raise TypeError(f"{cls.__name__}() takes no arguments")
else:
return original_new(cls)
arg.__new__ = staticmethod(__new__)
original_init_subclass = arg.__init_subclass__
# We need slightly different behavior if __init_subclass__
# is a bound method (likely if it was implemented in Python)
if isinstance(original_init_subclass, MethodType):
original_init_subclass = original_init_subclass.__func__
@functools.wraps(original_init_subclass)
def __init_subclass__(*args, **kwargs):
warn(msg, category=category, stacklevel=stacklevel + 1)
return original_init_subclass(*args, **kwargs)
arg.__init_subclass__ = classmethod(__init_subclass__)

and because these methods don't have a __module__ available (maybe they should?), we end up with the above exception.

Should we special case deprecated classes and other objects using the warnings.deprecated decorator in pydoc to display specific information? I don't think it's relevant to show the __new__ and __init_subclass__ overridden methods in the documentation output.

CPython versions tested on:

3.14

Operating systems tested on:

Linux

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibPython modules in the Lib dirtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions