From 829dbbb75353968bafcc46a1c67fbb9e5ab2057b Mon Sep 17 00:00:00 2001 From: David Salvisberg Date: Tue, 26 May 2026 11:18:33 +0200 Subject: [PATCH] fix: Fixes regression in backend logic for `argon2` and `bcrypt` For derived backends like `bcrypt_sha256` we were getting incorrect results for the first call to `_calc_checksum`, since we were starting over the inheritance chain from the top when arriving at `_NoBackend`, instead of from the spot where `_NoBackend` previously resided in the chain. --- passlib/handlers/argon2.py | 2 +- passlib/handlers/bcrypt.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/passlib/handlers/argon2.py b/passlib/handlers/argon2.py index 68d1bb4..5ba6cae 100644 --- a/passlib/handlers/argon2.py +++ b/passlib/handlers/argon2.py @@ -700,7 +700,7 @@ def _calc_checksum(self, secret): self._stub_requires_backend() # NOTE: have to use super() here so that we don't recursively # call subclass's wrapped _calc_checksum - return super()._calc_checksum(secret) + return super(argon2, self)._calc_checksum(secret) class _CffiBackend(_Argon2Common): diff --git a/passlib/handlers/bcrypt.py b/passlib/handlers/bcrypt.py index 121a12c..799cfbf 100644 --- a/passlib/handlers/bcrypt.py +++ b/passlib/handlers/bcrypt.py @@ -599,7 +599,7 @@ def _calc_checksum(self, secret): self._stub_requires_backend() # NOTE: have to use super() here so that we don't recursively # call subclass's wrapped _calc_checksum, e.g. bcrypt_sha256._calc_checksum - return self._calc_checksum(secret) + return super(bcrypt, self)._calc_checksum(secret) class _BcryptBackend(_BcryptCommon): @@ -770,17 +770,17 @@ class _wrapped_bcrypt(bcrypt): # def hash(cls, secret, **kwds): # # bypass bcrypt backend overriding this method # # XXX: would wrapping bcrypt make this easier than subclassing it? - # return super().hash(secret, **kwds) + # return super(_BcryptCommon, cls).hash(secret, **kwds) # # @classmethod # def verify(cls, secret, hash): # # bypass bcrypt backend overriding this method - # return super().verify(secret, hash) + # return super(_BcryptCommon, cls).verify(secret, hash) # # @classmethod # def genhash(cls, secret, hash): # # bypass bcrypt backend overriding this method - # return super().genhash(secret, hash) + # return super(_BcryptCommon, cls).genhash(secret, hash) @classmethod def _check_truncate_policy(cls, secret):