Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3346538
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 18, 20262026-05-18T01:18:57+00:00 2026-05-18T01:18:57+00:00

A naive attempt fails miserably: import hashlib class fred(hashlib.sha256): pass -> TypeError: Error when

  • 0

A naive attempt fails miserably:

import hashlib

class fred(hashlib.sha256):
    pass

-> TypeError: Error when calling the metaclass bases
       cannot create 'builtin_function_or_method' instances

Well, it turns out that hashlib.sha256 is a callable, not a class. Trying something a bit more creative doesn’t work either:

 import hashlib

 class fred(type(hashlib.sha256())):
     pass

 f = fred

 -> TypeError: cannot create 'fred' instances

Hmmm…

So, how do I do it?

Here is what I want to actually achieve:

class shad_256(sha256):
    """Double SHA - sha256(sha256(data).digest())
Less susceptible to length extension attacks than sha256 alone."""
    def digest(self):
        return sha256(sha256.digest(self)).digest()
    def hexdigest(self):
        return sha256(sha256.digest(self)).hexdigest()

Basically I want everything to pass through except when someone calls for a result I want to insert an extra step of my own. Is there a clever way I can accomplish this with __new__ or metaclass magic of some sort?

I have a solution I’m largely happy with that I posted as an answer, but I’m really interested to see if anybody can think of anything better. Either much less verbose with very little cost in readability or much faster (particularly when calling update) while still being somewhat readable.

Update: I ran some tests:

# test_sha._timehash takes three parameters, the hash object generator to use,
# the number of updates and the size of the updates.

# Built in hashlib.sha256
$ python2.7 -m timeit -n 100 -s 'import test_sha, hashlib' 'test_sha._timehash(hashlib.sha256, 20000, 512)'
100 loops, best of 3: 104 msec per loop

# My wrapper based approach (see my answer)
$ python2.7 -m timeit -n 100 -s 'import test_sha, hashlib' 'test_sha._timehash(test_sha.wrapper_shad_256, 20000, 512)'
100 loops, best of 3: 108 msec per loop

# Glen Maynard's getattr based approach
$ python2.7 -m timeit -n 100 -s 'import test_sha, hashlib' 'test_sha._timehash(test_sha.getattr_shad_256, 20000, 512)'
100 loops, best of 3: 103 msec per loop
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-18T01:18:57+00:00Added an answer on May 18, 2026 at 1:18 am

    Just use __getattr__ to cause all attributes that you don’t define yourself to fall back on the underlying object:

    import hashlib
    
    class shad_256(object):
        """
        Double SHA - sha256(sha256(data).digest())
        Less susceptible to length extension attacks than sha256 alone.
    
        >>> s = shad_256('hello world')
        >>> s.digest_size
        32
        >>> s.block_size
        64
        >>> s.sha256.hexdigest()
        'b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9'
        >>> s.hexdigest()
        'bc62d4b80d9e36da29c16c5d4d9f11731f36052c72401a76c23c0fb5a9b74423'
        >>> s.nonexistant()
        Traceback (most recent call last):
        ...
        AttributeError: '_hashlib.HASH' object has no attribute 'nonexistant'
        >>> s2 = s.copy()
        >>> s2.digest() == s.digest()
        True
        >>> s2.update("text")
        >>> s2.digest() == s.digest()
        False
        """
        def __init__(self, data=None):
            self.sha256 = hashlib.sha256()
            if data is not None:
                self.update(data)
    
        def __getattr__(self, key):
            return getattr(self.sha256, key)
    
        def _get_final_sha256(self):
            return hashlib.sha256(self.sha256.digest())
    
        def digest(self):
            return self._get_final_sha256().digest()
    
        def hexdigest(self):
            return self._get_final_sha256().hexdigest()
    
        def copy(self):
            result = shad_256()
            result.sha256 = self.sha256.copy()
            return result
    
    if __name__ == "__main__":
        import doctest
        doctest.testmod()
    

    This mostly eliminates the overhead for update calls, but not completely. If you want to completely eliminate it, add this to __init__ (and correspondingly in copy):

    self.update = self.sha256.update
    

    That will eliminate the extra __getattr__ call when looking up update.

    This all takes advantage of one of the more useful and often overlooked properties of Python member functions: function binding. Recall that you can do this:

    a = "hello"
    b = a.upper
    b()
    

    because taking a reference to a member function doesn’t return the original function, but a binding of that function to its object. That’s why, when __getattr__ above returns self.sha256.update, the returned function correctly operates on self.sha256, not self.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a large application written in native C++. I also have a class
I am starting with a file containing a list of hundreds of files (full
We have a script to delete the svn:mergeinfo property from all folders inside a
Adobe reference specifically points this out as a limitation. Here's the note in the
I'm trying to write a Linq query which fetches all users whose first or
I have a command bean ( FooList ) which has a property which is
Assume a method with the following signature: public static void foo(String arg1, String args2,
In Haskell, if I write fac n = facRec n 1 where facRec 0
At first glance, this question may seem like a duplicate of How to detect

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.