Does hashlib support a file mode?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Fri Jul 8 09:42:47 CEST 2011


Phlip wrote:

>> I worded that poorly. None is (AFAIK) the only instance of NoneType, but
>> I should've clarified the difference.> The is operator does not compare
>> types, it compares instances for identity.
> 
> None is typesafe, because it's strongly typed.

Everything in Python is strongly typed. Why single out None?

Python has strongly-typed objects, dynamically typed variables, and a
philosophy of preferring duck-typing over explicit type checks when
possible.


> However, what's even MORE X-safe (for various values of X) is a method
> that takes LESS for its arguments. That's why I switched from passing
> an object to passing a type, because the more restrictive argument
> type is more typesafe.

It seems to me that you are defeating duck-typing, and needlessly
restricting what the user can pass, for dubious or no benefit. I still
don't understand what problems you think you are avoiding with this tactic.



> However, the MOST X-safe version so far simply passes a string, and
> uses hashlib the way it designs to be used:
> 
> def file_to_hash(path, hash_type):
>     hash = hashlib.new(hash_type)
>     with open(path, 'rb') as f:
>         while True:
>             s = f.read(8192)
>             if not s:  break
>             hash.update(s)
>     return hash.hexdigest()


There is no advantage to this that I can see. It limits the caller to using
only hashes in hashlib. If the caller wants to provide her own hashing
algorithm, your function will not support it.

A more reasonable polymorphic version might be:

def file_to_hash(path, hash='md5', blocksize=8192):
    # FIXME is md5 a sensible default hash?
    if isinstance(hash, str):
        # Allow the user to specify the hash by name.
        hash = hashlib.new(hash)
    else:
        # Otherwise hash must be an object that implements the 
        # hashlib interface, i.e. a callable that returns an 
        # object with appropriate update and hexdigest methods.
        hash = hash()
    with open(path, 'rb') as f:
        while True:
            s = f.read(blocksize)
            if not s:  break
            hash.update(s)
    return hash.hexdigest()





-- 
Steven




More information about the Python-list mailing list