Change in partialmethod behaviour in python3.11

Hi there.

A library that I use testsuite fails in python3.11. I debugged it, and found that it’s due to them using partialmethod in a funny way that the behavior has changed in python3.11.

Here is a minimal use case that demonstrates this:

from functools import partialmethod


class Cell:
    def __init__(self):
        self.alive = False

    def set_state(self, state):
        self.alive = bool(state)


class Wrapper:
    def set_state_wrap(self, cell: Cell, state):
        cell.set_state(state)


wrapper = Wrapper()

Cell.set_alive = partialmethod(wrapper.set_state_wrap, True)

cell = Cell()
cell.set_alive()
print(cell.alive)

In python3.10, this prints True. In python3.11 it errors with:

Traceback (most recent call last):
  File "/home/gary/partialmethod.py", line 23, in <module>
    c.set_alive()
TypeError: Wrapper.set_state_wrap() missing 1 required positional argument: 'state'

The arguments passed to Wrapper.set_state_wrap are:
python3.10: wrapper, cell, True
python3.11: cell, True

So partialmethod is forgetting that set_state_wrap is a method of wrapper, and it needs to pass that in as the first arg.

Personally I feel that the way they are using partialmethod is not great, and I’m going to submit a PR to the library to fix this.

However I’ve looked for documentation of this change, but could not find any. It feels like this Is maybe a bug, or is a bug that it’s not documented. Should I log it?

Thanks for finding this. Yes, please open a bug report issue at Sign in to GitHub · GitHub

1 Like

Done: Behaviour change in partialmethod in Python3.11 · Issue #99152 · python/cpython · GitHub

1 Like