Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #8988 > unrolled thread

Re: Does hashlib support a file mode?

Started byCarl Banks <pavlovevidence@gmail.com>
First post2011-07-06 13:25 -0700
Last post2011-07-09 14:44 +1000
Articles 14 — 4 participants

Back to article view | Back to comp.lang.python


Contents

  Re: Does hashlib support a file mode? Carl Banks <pavlovevidence@gmail.com> - 2011-07-06 13:25 -0700
    Re: Does hashlib support a file mode? Phlip <phlip2005@gmail.com> - 2011-07-06 14:07 -0700
      Re: Does hashlib support a file mode? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-07-07 09:16 +1000
        Re: Does hashlib support a file mode? Andrew Berg <bahamutzero8825@gmail.com> - 2011-07-07 07:50 -0500
          Re: Does hashlib support a file mode? Phlip <phlip2005@gmail.com> - 2011-07-07 06:11 -0700
            Re: Does hashlib support a file mode? Andrew Berg <bahamutzero8825@gmail.com> - 2011-07-07 08:24 -0500
              Re: Does hashlib support a file mode? Phlip <phlip2005@gmail.com> - 2011-07-07 06:39 -0700
                Re: Does hashlib support a file mode? Andrew Berg <bahamutzero8825@gmail.com> - 2011-07-07 08:58 -0500
                  Re: Does hashlib support a file mode? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-07-08 11:46 +1000
                    Re: Does hashlib support a file mode? Andrew Berg <bahamutzero8825@gmail.com> - 2011-07-07 21:32 -0500
                      Re: Does hashlib support a file mode? Phlip <phlip2005@gmail.com> - 2011-07-07 20:26 -0700
                        Re: Does hashlib support a file mode? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-07-08 17:42 +1000
                          Re: Does hashlib support a file mode? Phlip <phlip2005@gmail.com> - 2011-07-08 06:03 -0700
                            Re: Does hashlib support a file mode? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-07-09 14:44 +1000

#8988 — Re: Does hashlib support a file mode?

FromCarl Banks <pavlovevidence@gmail.com>
Date2011-07-06 13:25 -0700
SubjectRe: Does hashlib support a file mode?
Message-ID<0c058f60-3fd7-4b67-85a2-0658b2bb1887@glegroupsg2000goo.googlegroups.com>
On Wednesday, July 6, 2011 12:07:56 PM UTC-7, Phlip wrote:
> If I call m = md5() twice, I expect two objects.
> 
> I am now aware that Python bends the definition of "call" based on
> where the line occurs. Principle of least surprise.

Phlip:

We already know about this violation of the least surprise principle; most of us acknowledge it as small blip in an otherwise straightforward and clean language.  (Incidentally, fixing it would create different surprises, but probably much less common ones.)

We've helped you with your problem, but you risk alienating those who helped you when you badmouth the whole language on account of this one thing, and you might not get such prompt help next time.  So try to be nice.

You are wrong about Python bending the definition of "call", though.  Surprising though it be, the Python language is very explicit that the default arguments are executed only once, when creating the function, *not* when calling it.


Carl Banks

[toc] | [next] | [standalone]


#8990

FromPhlip <phlip2005@gmail.com>
Date2011-07-06 14:07 -0700
Message-ID<9e976158-94c7-4e8b-8aa8-f0daa644b06d@fv14g2000vbb.googlegroups.com>
In reply to#8988
On Jul 6, 1:25 pm, Carl Banks <pavlovevide...@gmail.com> wrote:

> We already know about this violation of the least surprise principle; most of us acknowledge it as small blip in an otherwise straightforward and clean language.

Here's the production code we're going with - thanks again all:


def file_to_hash(path, hash_type=hashlib.md5):
    """
    Per: http://groups.google.com/group/comp.lang.python/browse_thread/thread/ea1c46f77ac1738c
    """

    hash = hash_type()

    with open(path, 'rb') as f:

        while True:
            s = f.read(8192)  #  CONSIDER:  io.DEFAULT_BUFFER_SIZE
            if not s:  break
            hash.update(s)

    return hash.hexdigest()

Note the fix also avoids comparing to None, which, as usual, is also
icky and less typesafe!

(And don't get me started about the extra lines needed to avoid THIS
atrocity!

        while s = f.read(8192):
            hash.update(s)

;)

[toc] | [prev] | [next] | [standalone]


#8997

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-07-07 09:16 +1000
Message-ID<4e14ecd4$0$29965$c3e8da3$5496439d@news.astraweb.com>
In reply to#8990
Phlip wrote:

> Note the fix also avoids comparing to None, which, as usual, is also
> icky and less typesafe!

"Typesafe"? Are you trying to make a joke?



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#9027

FromAndrew Berg <bahamutzero8825@gmail.com>
Date2011-07-07 07:50 -0500
Message-ID<mailman.739.1310043020.1164.python-list@python.org>
In reply to#8997
On 2011.07.06 06:16 PM, Steven D'Aprano wrote:
> Phlip wrote:
>
> > Note the fix also avoids comparing to None, which, as usual, is also
> > icky and less typesafe!
>
> "Typesafe"? Are you trying to make a joke?
Maybe he has a duck phobia. Maybe he denies the existence of ducks.
Maybe he doesn't like the sound of ducks. Maybe he just weighs the same
as a duck. In any case, duck tolerance is necessary to use Python
effectively.


On a side note, it turns out there's no word for the fear of ducks. The
closest phobia is anatidaephobia, which is the fear of being /watched/
by a duck.

[toc] | [prev] | [next] | [standalone]


#9028

FromPhlip <phlip2005@gmail.com>
Date2011-07-07 06:11 -0700
Message-ID<0cd66788-5603-421e-82fb-fa3ac089711c@u42g2000yqm.googlegroups.com>
In reply to#9027
> On 2011.07.06 06:16 PM, Steven D'Aprano wrote:> Phlip wrote:
>
> > > Note the fix also avoids comparing to None, which, as usual, is also
> > > icky and less typesafe!
>
> > "Typesafe"? Are you trying to make a joke?

No, I was pointing out that passing a type is more ... typesafe.

[toc] | [prev] | [next] | [standalone]


#9029

FromAndrew Berg <bahamutzero8825@gmail.com>
Date2011-07-07 08:24 -0500
Message-ID<mailman.740.1310045106.1164.python-list@python.org>
In reply to#9028
On 2011.07.07 08:11 AM, Phlip wrote:
> No, I was pointing out that passing a type is more ... typesafe.
None is a type.

>>> None.__class__
<class 'NoneType'>

[toc] | [prev] | [next] | [standalone]


#9030

FromPhlip <phlip2005@gmail.com>
Date2011-07-07 06:39 -0700
Message-ID<6218f9fc-2155-4f31-aa07-fe2caadac190@y30g2000yqb.googlegroups.com>
In reply to#9029
On Jul 7, 6:24 am, Andrew Berg <bahamutzero8...@gmail.com> wrote:
> On 2011.07.07 08:11 AM, Phlip wrote:> No, I was pointing out that passing a type is more ... typesafe.
>
> None is a type.

I never said it wasn't.

[toc] | [prev] | [next] | [standalone]


#9031

FromAndrew Berg <bahamutzero8825@gmail.com>
Date2011-07-07 08:58 -0500
Message-ID<mailman.741.1310047140.1164.python-list@python.org>
In reply to#9030
On 2011.07.07 08:39 AM, Phlip wrote:
> On Jul 7, 6:24 am, Andrew Berg <bahamutzero8...@gmail.com> wrote:
> > On 2011.07.07 08:11 AM, Phlip wrote:> No, I was pointing out that passing a type is more ... typesafe.
> >
> > None is a type.
>
> I never said it wasn't.
You are talking about this code, right?

def file_to_hash(path, m=None):
    if m is None:
        m = hashlib.md5()

What's not a type? The is operator compares types (m's value isn't the
only thing compared here; even an separate instance of the exact same
type would make it return False), and m can't be undefined.

[toc] | [prev] | [next] | [standalone]


#9063

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-07-08 11:46 +1000
Message-ID<4e166165$0$29983$c3e8da3$5496439d@news.astraweb.com>
In reply to#9031
Andrew Berg wrote:

> On 2011.07.07 08:39 AM, Phlip wrote:
>> On Jul 7, 6:24 am, Andrew Berg <bahamutzero8...@gmail.com> wrote:
>> > On 2011.07.07 08:11 AM, Phlip wrote:> No, I was pointing out that
>> > passing a type is more ... typesafe.
>> >
>> > None is a type.
>>
>> I never said it wasn't.

Unfortunately, it isn't.

None is not a type, it is an instance.

>>> isinstance(None, type)  # is None a type?
False
>>> isinstance(None, type(None))  # is None an instance of None's type?
True

So None is not itself a type, although it *has* a type:

>>> type(None)
<type 'NoneType'>
>>> isinstance(type(None), type)  # is NoneType itself a type?
True


> You are talking about this code, right?
> 
> def file_to_hash(path, m=None):
>     if m is None:
>         m = hashlib.md5()
> 
> What's not a type? The is operator compares types (m's value isn't the
> only thing compared here; even an separate instance of the exact same
> type would make it return False), and m can't be undefined.

The is operator does not compare types, it compares instances for identity.
There is no need for is to ever care about the type of the arguments --
that's just a waste of time, since a fast identity (memory location) test
is sufficient.

This is why I initially thought that Phlip was joking when he suggested
that "m is None" could be type-unsafe. It doesn't matter what type m
has, "m is <anything>" will always be perfectly safe. 




-- 
Steven

[toc] | [prev] | [next] | [standalone]


#9065

FromAndrew Berg <bahamutzero8825@gmail.com>
Date2011-07-07 21:32 -0500
Message-ID<mailman.766.1310092389.1164.python-list@python.org>
In reply to#9063
On 2011.07.07 08:46 PM, Steven D'Aprano wrote:
> None is not a type, it is an instance.
>
> >>> isinstance(None, type)  # is None a type?
> False
> >>> isinstance(None, type(None))  # is None an instance of None's type?
> True
>
> So None is not itself a type, although it *has* a type:
>
> >>> type(None)
> <type 'NoneType'>
> >>> isinstance(type(None), type)  # is NoneType itself a type?
> True
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.
> There is no need for is to ever care about the type of the arguments --
> that's just a waste of time, since a fast identity (memory location) test
> is sufficient.
"Compare" was the wrong word. I figured the interpreter doesn't
explicitly compare types, but obviously identical instances are going to
be of the same type.

[toc] | [prev] | [next] | [standalone]


#9067

FromPhlip <phlip2005@gmail.com>
Date2011-07-07 20:26 -0700
Message-ID<06e6fd07-6630-41eb-9dc9-a9bf5f7524cb@p31g2000vbs.googlegroups.com>
In reply to#9065
> 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.

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.

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()

[toc] | [prev] | [next] | [standalone]


#9071

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-07-08 17:42 +1000
Message-ID<4e16b4f8$0$29983$c3e8da3$5496439d@news.astraweb.com>
In reply to#9067
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

[toc] | [prev] | [next] | [standalone]


#9077

FromPhlip <phlip2005@gmail.com>
Date2011-07-08 06:03 -0700
Message-ID<0c552105-dd13-40d4-8265-d06097adda18@d22g2000yqn.googlegroups.com>
In reply to#9071
On Jul 8, 12:42 am, Steven D'Aprano <steve
+comp.lang.pyt...@pearwood.info> wrote:
> 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?

You do understand these cheap shots are bad for conversations, right?

I didn't single out None. When did you stop raping your mother?

[toc] | [prev] | [next] | [standalone]


#9106

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-07-09 14:44 +1000
Message-ID<4e17dcc0$0$29966$c3e8da3$5496439d@news.astraweb.com>
In reply to#9077
Phlip wrote:

> On Jul 8, 12:42 am, Steven D'Aprano <steve
> +comp.lang.pyt...@pearwood.info> wrote:
>> 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?
> 
> You do understand these cheap shots are bad for conversations, right?
> 
> I didn't single out None. 

Phlip, I'm not an idiot, please don't pee on my leg and tell me it's
raining. In the very sentence you quote above, you clearly and obviously
single out None:

"None is typesafe, because it's strongly typed."

Yes, None is strongly typed -- like everything else in Python. I don't
understand what point you are trying to make. Earlier you claimed that
identity testing for None is type-unsafe (or at least *less* type-safe,
whatever that means):

"Note the fix also avoids comparing to None, which, as usual, is also icky
and less typesafe!"

then you say None is type-safe -- if there is a coherent message in your
posts, it is too cryptic for me.


> When did you stop raping your mother? 

What makes you think I've stopped?



-- 
Steven

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web