Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #8988 > unrolled thread
| Started by | Carl Banks <pavlovevidence@gmail.com> |
|---|---|
| First post | 2011-07-06 13:25 -0700 |
| Last post | 2011-07-09 14:44 +1000 |
| Articles | 14 — 4 participants |
Back to article view | Back to comp.lang.python
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
| From | Carl Banks <pavlovevidence@gmail.com> |
|---|---|
| Date | 2011-07-06 13:25 -0700 |
| Subject | Re: 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]
| From | Phlip <phlip2005@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2011-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]
| From | Andrew Berg <bahamutzero8825@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Phlip <phlip2005@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Andrew Berg <bahamutzero8825@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Phlip <phlip2005@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Andrew Berg <bahamutzero8825@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2011-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]
| From | Andrew Berg <bahamutzero8825@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Phlip <phlip2005@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2011-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]
| From | Phlip <phlip2005@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2011-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