Mailing List Archive

1 2 3  View All
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
Oleg Broytman wrote:
> On Wed, Apr 04, 2012 at 05:47:16PM +0200, Lennart Regebro wrote:
>> On Tue, Apr 3, 2012 at 18:07, Ethan Furman <ethan@stoneleaf.us> wrote:
>>> What's unclear about returning None if no clocks match?
>> Nothing, but having to check error values on return functions are not
>> what you typically do in Python. Usually, Python functions that fail
>> raise an error.
>
> Absolutely. "Errors should never pass silently."

Again, what's the /intent/? No matching clocks does not have to be an
error.


>> Please don't force Python users to write pseudo-C code in Python.
>
> +1. Pythonic equivalent of "get_clock(THIS) or get_clok(THAT)" is
>
> for flag in (THIS, THAT):
> try:
> clock = get_clock(flag)
> except:
> pass
> else:
> break
> else:
> raise ValueError('Cannot get clock, tried THIS and THAT')


Wow -- you'd rather write nine lines of code instead of three?

clock = get_clock(THIS) or get_clock(THAT)
if clock is None:
raise ValueError('Cannot get clock, tried THIS and THAT')

~Ethan~
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
Georg Brandl wrote:
> Am 04.04.2012 18:18, schrieb Ethan Furman:
>> Lennart Regebro wrote:
>>> On Tue, Apr 3, 2012 at 18:07, Ethan Furman <ethan@stoneleaf.us> wrote:
>>>> What's unclear about returning None if no clocks match?
>>> Nothing, but having to check error values on return functions are not
>>> what you typically do in Python. Usually, Python functions that fail
>>> raise an error. Please don't force Python users to write pseudo-C code
>>> in Python.
>> You mean like the dict.get() function?
>>
>> --> repr({}.get('missing'))
>> 'None'
>
> Strawman: this is not a failure.

Also not a very good example -- if 'missing' was there with a value of
None the two situations could not be distinguished with the one call.

At any rate, the point is that there is nothing inherently wrong nor
unPythonic about a function returning None instead of raising an exception.

~Ethan~
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
On Wed, Apr 04, 2012 at 11:03:02AM -0700, Ethan Furman wrote:
> Oleg Broytman wrote:
> > . Pythonic equivalent of "get_clock(THIS) or get_clok(THAT)" is
> >
> >for flag in (THIS, THAT):
> > try:
> > clock = get_clock(flag)
> > except:
> > pass
> > else:
> > break
> >else:
> > raise ValueError('Cannot get clock, tried THIS and THAT')
>
>
> Wow -- you'd rather write nine lines of code instead of three?
>
> clock = get_clock(THIS) or get_clock(THAT)
> if clock is None:
> raise ValueError('Cannot get clock, tried THIS and THAT')

Yes - to force people to write the last two lines. Without forcing
most programmers will skip them.

Oleg.
--
Oleg Broytman http://phdru.name/ phd@phdru.name
Programmers don't die, they just GOSUB without RETURN.
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
Oleg Broytman wrote:
> On Wed, Apr 04, 2012 at 11:03:02AM -0700, Ethan Furman wrote:
>> Oleg Broytman wrote:
>>> . Pythonic equivalent of "get_clock(THIS) or get_clok(THAT)" is
>>>
>>> for flag in (THIS, THAT):
>>> try:
>>> clock = get_clock(flag)
>>> except:
>>> pass
>>> else:
>>> break
>>> else:
>>> raise ValueError('Cannot get clock, tried THIS and THAT')
>>
>> Wow -- you'd rather write nine lines of code instead of three?
>>
>> clock = get_clock(THIS) or get_clock(THAT)
>> if clock is None:
>> raise ValueError('Cannot get clock, tried THIS and THAT')
>
> Yes - to force people to write the last two lines. Without forcing
> most programmers will skip them.

Forced? I do not use Python to be forced to use one style of
programming over another.

And it's not like returning None will allow some clock calls to work but
not others -- as soon as they try to use it, it will raise an exception.

~Ethan~
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
On 04Apr2012 19:47, Georg Brandl <g.brandl@gmx.net> wrote:
| Am 04.04.2012 18:18, schrieb Ethan Furman:
| > Lennart Regebro wrote:
| >> On Tue, Apr 3, 2012 at 18:07, Ethan Furman <ethan@stoneleaf.us> wrote:
| >>> What's unclear about returning None if no clocks match?
| >>
| >> Nothing, but having to check error values on return functions are not
| >> what you typically do in Python. Usually, Python functions that fail
| >> raise an error. Please don't force Python users to write pseudo-C code
| >> in Python.
| >
| > You mean like the dict.get() function?
| >
| > --> repr({}.get('missing'))
| > 'None'
|
| Strawman: this is not a failure.

And neither is get_clock() returning None. get_clock() is an inquiry
function, and None is a legitimate response when no clock is
satisfactory, just as a dict has no key for a get().

Conversely, monotonic() ("gimme the time!") and indeed time() should
raise an exception if there is no clock. They're, for want of a word,
"live" functions you would routinely embed in a calculation.

So not so much a straw man as a relevant illuminating example.
--
Cameron Simpson <cs@zip.com.au> DoD#743
http://www.cskk.ezoshosting.com/cs/

A crash reduces
your expensive computer
to a simple stone.
- Haiku Error Messages http://www.salonmagazine.com/21st/chal/1998/02/10chal2.html
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 [ In reply to ]
Oleg Broytman wrote:
> On Wed, Apr 04, 2012 at 11:03:02AM -0700, Ethan Furman wrote:
>> Oleg Broytman wrote:
>>> . Pythonic equivalent of "get_clock(THIS) or get_clok(THAT)" is
>>>
>>> for flag in (THIS, THAT):
>>> try:
>>> clock = get_clock(flag)
>>> except:
>>> pass
>>> else:
>>> break
>>> else:
>>> raise ValueError('Cannot get clock, tried THIS and THAT')
>>
>> Wow -- you'd rather write nine lines of code instead of three?
>>
>> clock = get_clock(THIS) or get_clock(THAT)
>> if clock is None:
>> raise ValueError('Cannot get clock, tried THIS and THAT')
>
> Yes - to force people to write the last two lines. Without forcing
> most programmers will skip them.

You're not my real Dad! You can't tell me what to do!

*wink*

This level of paternalism is unnecessary. It's not your job to "force"
programmers to do anything. If people skip the test for None, they will get an
exception as soon as they try to use None as an exception, and then they will
fix their broken code.

Although I don't like the get_clock() API, I don't think this argument against
it is a good one. Exceptions are the *usual* error-handling mechanism in
Python, but they are not the *only* mechanism, there are others, and it is
perfectly okay to use non-exception based failures when appropriate. This is
one such example.

"Return None on failure" is how re.match() and re.search() work, and it is a
good design for when you have multiple fallbacks on failure.

result = re.match(spam, s) or re.match(ham, s) or re.match(eggs, s)
if result is None:
raise ValueError('could not find spam, ham or eggs')


This is a *much* better design than nested tries:

try:
result = re.match(spam, s)
except ValueError:
try:
result = re.match(ham, s)
except ValueError:
try:
result = re.match(eggs, s)
except ValueError:
raise ValueError('could not find spam, ham or eggs')


Wow. Now *that* is ugly code. There's nothing elegant or Pythonic about being
forced to write that out of a misplaced sense of purity.


--
Steven

_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
On Wed, Apr 04, 2012 at 12:52:00PM -0700, Ethan Furman wrote:
> Oleg Broytman wrote:
> >On Wed, Apr 04, 2012 at 11:03:02AM -0700, Ethan Furman wrote:
> >>Oleg Broytman wrote:
> >>> . Pythonic equivalent of "get_clock(THIS) or get_clok(THAT)" is
> >>>
> >>>for flag in (THIS, THAT):
> >>> try:
> >>> clock = get_clock(flag)
> >>> except:
> >>> pass
> >>> else:
> >>> break
> >>>else:
> >>> raise ValueError('Cannot get clock, tried THIS and THAT')
> >>
> >>Wow -- you'd rather write nine lines of code instead of three?
> >>
> >>clock = get_clock(THIS) or get_clock(THAT)
> >>if clock is None:
> >> raise ValueError('Cannot get clock, tried THIS and THAT')
> >
> > Yes - to force people to write the last two lines. Without forcing
> >most programmers will skip them.
>
> Forced? I do not use Python to be forced to use one style of
> programming over another.

Then it's strange you are using Python with its strict syntax
(case-sensitivity, forced indents), ubiquitous exceptions, limited
syntax of lambdas and absence of code blocks (read - forced functions),
etc.

> And it's not like returning None will allow some clock calls to work
> but not others -- as soon as they try to use it, it will raise an
> exception.

There is a philosophical distinction between EAFP and LBYL. I am
mostly proponent of LBYL.
Well, I am partially retreat. "Errors should never pass silently.
Unless explicitly silenced." get_clock(FLAG, on_error=None) could return
None.

Oleg.
--
Oleg Broytman http://phdru.name/ phd@phdru.name
Programmers don't die, they just GOSUB without RETURN.
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 [ In reply to ]
On 05Apr2012 08:50, Steven D'Aprano <steve@pearwood.info> wrote:
| Although I don't like the get_clock() API, I don't think this argument against
| it is a good one.

Just to divert briefly; you said in another post you didn't like the API
and (also/because?) it didn't help discoverability.

My core objective was to allow users to query for clocks, and ideally
enumerate and inspect all clocks. Without the caller having platform
specific knowledge.

Allowing for the sake of discussion that this is desirable, what would
you propose as an API instead of get_clock() (and its friend, get_clocks()
for enumeration, that I should stuff into the code).

Cheers,
--
Cameron Simpson <cs@zip.com.au> DoD#743
http://www.cskk.ezoshosting.com/cs/

Q: How many user support people does it take to change a light bulb?
A: We have an exact copy of the light bulb here and it seems to be
working fine. Can you tell me what kind of system you have?
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
On Thu, Apr 5, 2012 at 8:05 AM, Oleg Broytman <phd@phdru.name> wrote:
>   Well, I am partially retreat. "Errors should never pass silently.
> Unless explicitly silenced." get_clock(FLAG, on_error=None) could return
> None.

I still don't see what's erroneous about returning None when asked for
an object that is documented to possibly not exist, ever, in some
implementations. Isn't that precisely why None exists?
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
On Thu, Apr 05, 2012 at 10:06:38PM +0900, Stephen J. Turnbull wrote:
> On Thu, Apr 5, 2012 at 8:05 AM, Oleg Broytman <phd@phdru.name> wrote:
> >   Well, I am partially retreat. "Errors should never pass silently.
> > Unless explicitly silenced." get_clock(FLAG, on_error=None) could return
> > None.
>
> I still don't see what's erroneous about returning None when asked for
> an object that is documented to possibly not exist, ever, in some
> implementations. Isn't that precisely why None exists?

Why doesn't open() return None for a non-existing file? or
socket.gethostbyname() for a non-existing name?

Oleg.
--
Oleg Broytman http://phdru.name/ phd@phdru.name
Programmers don't die, they just GOSUB without RETURN.
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
On Thu, Apr 5, 2012 at 10:34 PM, Oleg Broytman <phd@phdru.name> wrote:

>   Why doesn't open() return None for a non-existing file? or
> socket.gethostbyname() for a non-existing name?

That's not an answer to my question, because those calls have very
important use cases where the user knows the object exists (and in
fact in some cases open() will create it for him), so that failure to
exist is indeed a (user) error (such as a misspelling). I find it
hard to imagine use cases where "file = open(thisfile) or
open(thatfile)" makes sense. Not even for the case where thisfile ==
'script.pyc' and thatfile == 'script.py'.

The point of the proposed get_clock(), OTOH, is to ask if an object
with certain characteristics exists, and the fact that it returns the
clock rather than True if found is a matter of practical convenience.
Precisely because "clock = get_clock(best) or get_clock(better) or
get_clock(acceptable)" does make sense.
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
On Thu, Apr 05, 2012 at 11:45:06PM +0900, Stephen J. Turnbull wrote:
> On Thu, Apr 5, 2012 at 10:34 PM, Oleg Broytman <phd@phdru.name> wrote:
> >   Why doesn't open() return None for a non-existing file? or
> > socket.gethostbyname() for a non-existing name?
>
> That's not an answer to my question, because those calls have very
> important use cases where the user knows the object exists (and in
> fact in some cases open() will create it for him), so that failure to
> exist is indeed a (user) error (such as a misspelling). I find it
> hard to imagine use cases where "file = open(thisfile) or
> open(thatfile)" makes sense. Not even for the case where thisfile ==
> 'script.pyc' and thatfile == 'script.py'.

Counterexamples - any configuration file: a program looks for its config
at $HOME and not finding it there looks in /etc. So
config = open('~/.someprogram.config') or open('/etc/someprogram/config')
would make sense. The absence of any of these files is not an error at
all - the program just starts with default configuration. So if the
resulting config in the code above would be None - it's still would be
ok. But Python doesn't allow that.
Some configuration files are constructed by combining a number of
user-defined and system-defined files. E.g., the mailcap database. It
should be something like
combined_database = [.db for db in (
open('/etc/mailcap'),
open('/usr/etc/mailcap'),
open('/usr/local/etc/mailcap'),
open('~/.mailcap'),
) if db]
But no way - open() raises IOError, not return None. And I think it is
the right way. Those who want to write the code similar to the examples
above - explicitly suppress exceptions by writing wrappers.

> The point of the proposed get_clock(), OTOH, is to ask if an object
> with certain characteristics exists, and the fact that it returns the
> clock rather than True if found is a matter of practical convenience.
> Precisely because "clock = get_clock(best) or get_clock(better) or
> get_clock(acceptable)" does make sense.

Oleg.
--
Oleg Broytman http://phdru.name/ phd@phdru.name
Programmers don't die, they just GOSUB without RETURN.
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
On Thu, 05 Apr 2012 19:22:17 +0400, Oleg Broytman <phd@phdru.name> wrote:
> On Thu, Apr 05, 2012 at 11:45:06PM +0900, Stephen J. Turnbull wrote:
> > On Thu, Apr 5, 2012 at 10:34 PM, Oleg Broytman <phd@phdru.name> wrote:
> > >   Why doesn't open() return None for a non-existing file? or
> > > socket.gethostbyname() for a non-existing name?
> >
> > That's not an answer to my question, because those calls have very
> > important use cases where the user knows the object exists (and in
> > fact in some cases open() will create it for him), so that failure to
> > exist is indeed a (user) error (such as a misspelling). I find it
> > hard to imagine use cases where "file = open(thisfile) or
> > open(thatfile)" makes sense. Not even for the case where thisfile ==
> > 'script.pyc' and thatfile == 'script.py'.
>
> Counterexamples - any configuration file: a program looks for its config
> at $HOME and not finding it there looks in /etc. So
> config = open('~/.someprogram.config') or open('/etc/someprogram/config')
> would make sense. The absence of any of these files is not an error at
> all - the program just starts with default configuration. So if the
> resulting config in the code above would be None - it's still would be
> ok. But Python doesn't allow that.
> Some configuration files are constructed by combining a number of
> user-defined and system-defined files. E.g., the mailcap database. It
> should be something like
> combined_database = [.db for db in (
> open('/etc/mailcap'),
> open('/usr/etc/mailcap'),
> open('/usr/local/etc/mailcap'),
> open('~/.mailcap'),
> ) if db]
> But no way - open() raises IOError, not return None. And I think it is
> the right way. Those who want to write the code similar to the examples
> above - explicitly suppress exceptions by writing wrappers.

Ah, but the actual code in the mimetypes module (whose list is even
longer) looks like this:

for file in files:
if os.path.isfile(file):
db.read(file)

That is, Python provides a query function that doesn't raise an error.

Do you really think we need to add a third clock function (the query
function) that just returns True or False? Maybe we do, if actually
creating the clock could raise an error even if exists, as is the case
for 'open'.

(But unless I'm confused none of this has anything to do with Victor's
PEP as currently proposed :)

--David
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
On Thu, Apr 05, 2012 at 07:22:17PM +0400, Oleg Broytman wrote:
> On Thu, Apr 05, 2012 at 11:45:06PM +0900, Stephen J. Turnbull wrote:
> > find it
> > hard to imagine use cases where "file = open(thisfile) or
> > open(thatfile)" makes sense. Not even for the case where thisfile ==
> > 'script.pyc' and thatfile == 'script.py'.
>
> Counterexamples - any configuration file: a program looks for its config
> at $HOME and not finding it there looks in /etc. So
> config = open('~/.someprogram.config') or open('/etc/someprogram/config')
> would make sense.

A counterexample with gethostbyname - a list of proxies. It's not an
error if some or even all proxies in the list are down - one just
connect to the first that's up. So a chain like
proxy_addr = gethostbyname(FIRST) or gethostbyname(SECOND)
would make sense.

Oleg.
--
Oleg Broytman http://phdru.name/ phd@phdru.name
Programmers don't die, they just GOSUB without RETURN.
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
On Thu, Apr 05, 2012 at 11:38:13AM -0400, R. David Murray wrote:
> Do you really think we need to add a third clock function (the query
> function) that just returns True or False? Maybe we do, if actually
> creating the clock could raise an error even if exists, as is the case
> for 'open'.

May be we do. Depends on the usage patterns.

Oleg.
--
Oleg Broytman http://phdru.name/ phd@phdru.name
Programmers don't die, they just GOSUB without RETURN.
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
Oleg Broytman wrote:
> On Wed, Apr 04, 2012 at 12:52:00PM -0700, Ethan Furman wrote:
>> Forced? I do not use Python to be forced to use one style of
>> programming over another.
>
> Then it's strange you are using Python with its strict syntax
> (case-sensitivity, forced indents), ubiquitous exceptions, limited
> syntax of lambdas and absence of code blocks (read - forced functions),
> etc.

I come from assembly -- 'a' and 'A' are *not* the same.

indents -- I already used them; finding a language that gave them the
same importance I did was incredible.

exceptions -- Python uses them, true, but I don't have to in my own code
(I do, but that's besides the point).

lambdas -- they work just fine for my needs.

etc.


>> And it's not like returning None will allow some clock calls to work
>> but not others -- as soon as they try to use it, it will raise an
>> exception.
>
> There is a philosophical distinction between EAFP and LBYL. I am
> mostly proponent of LBYL.
> Well, I am partially retreat. "Errors should never pass silently.
> Unless explicitly silenced." get_clock(FLAG, on_error=None) could return
> None.

It's only an error if it's documented that way and, more importantly,
thought of that way. The re module is a good example: if it can't find
what you're looking for it returns None -- it does *not* raise a
NotFound exception.

I see get_clock() the same way: I need a clock that does xyz... None?
Okay, there isn't one.

~Ethan~
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
On Thu, Apr 05, 2012 at 11:56:00AM -0700, Ethan Furman wrote:
> It's only an error if it's documented that way and, more
> importantly, thought of that way. The re module is a good example:
> if it can't find what you're looking for it returns None -- it does
> *not* raise a NotFound exception.

But open() raises IOError. ''.find('a') returns -1 but ''.index('a')
raises ValueError.
So we can argue in circles both ways, there are too many arguments
pro and contra. Python is just too inconsistent to be consistently
argued over. ;-)

Oleg.
--
Oleg Broytman http://phdru.name/ phd@phdru.name
Programmers don't die, they just GOSUB without RETURN.
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
Oleg Broytman wrote:
> On Thu, Apr 05, 2012 at 11:56:00AM -0700, Ethan Furman wrote:
>> It's only an error if it's documented that way and, more
>> importantly, thought of that way. The re module is a good example:
>> if it can't find what you're looking for it returns None -- it does
>> *not* raise a NotFound exception.
>
> But open() raises IOError. ''.find('a') returns -1 but ''.index('a')
> raises ValueError.
> So we can argue in circles both ways, there are too many arguments
> pro and contra. Python is just too inconsistent to be consistently
> argued over. ;-)

Indeed -- I think we have reached an agreement! Now if you'll just
agree that returning None in this case is better... ;)

~Ethan~
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
On 05Apr2012 03:05, Oleg Broytman <phd@phdru.name> wrote:
| On Wed, Apr 04, 2012 at 12:52:00PM -0700, Ethan Furman wrote:
| > Forced? I do not use Python to be forced to use one style of
| > programming over another.
|
| Then it's strange you are using Python with its strict syntax
| (case-sensitivity, forced indents), ubiquitous exceptions, limited
| syntax of lambdas and absence of code blocks (read - forced functions),
| etc.

But exceptions are NOT ubiquitous, nor should they be. They're a very
popular and often apt way to handle certain circumstances, that's all.
--
Cameron Simpson <cs@zip.com.au> DoD#743
http://www.cskk.ezoshosting.com/cs/

On the one hand I knew that programs could have a compelling and deep logical
beauty, on the other hand I was forced to admit that most programs are
presented in a way fit for mechanical execution, but even if of any beauty at
all, totally unfit for human appreciation. - Edsger W. Dijkstra
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
On 06Apr2012 00:15, Oleg Broytman <phd@phdru.name> wrote:
| So we can argue in circles both ways, there are too many arguments
| pro and contra. Python is just too inconsistent to be consistently
| argued over. ;-)

Bah! I think these threads demonstrate that we can consistently argue
over Python for weeks per topic, sometimes months and years.
--
Cameron Simpson <cs@zip.com.au> DoD#743
http://www.cskk.ezoshosting.com/cs/

Sam Jones <samjones@leo.unm.edu> on the Nine Types of User:

Frying Pan/Fire Tactician - "It didn't work with the data set we had, so I
fed in my aunt's recipe for key lime pie."
Advantages: Will usually fix error.
Disadvantages: 'Fix' is defined VERY loosely here.
Symptoms: A tendancy to delete lines that get errors instead of fixing
them.
Real Case: One user complained that their program executed, but didn't
do anything. The scon looked at it for twenty minutes before
realizing that they'd commented out EVERY LINE. The user
said, "Well, that was the only way I could get it to compile."
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
On Fri, Apr 6, 2012 at 12:22 AM, Oleg Broytman <phd@phdru.name> wrote:
> On Thu, Apr 05, 2012 at 11:45:06PM +0900, Stephen J. Turnbull wrote:
>> On Thu, Apr 5, 2012 at 10:34 PM, Oleg Broytman <phd@phdru.name> wrote:
>> >   Why doesn't open() return None for a non-existing file? or
>> > socket.gethostbyname() for a non-existing name?
>>
>> That's not an answer to my question, because those calls have very
>> important use cases

Note, implicit existential quantifier.

>   Counterexamples

Not an argument against an existential quantifier.

> But Python doesn't allow [.use of conditional constructs when opening a series of files, one must trap exceptions].

True. Python needs to make a choice, and the existence of important
cases where the user knows that the object (file) exists makes it
plausible that the user would prefer an Exception. Also, open() is
intended to be a fairly thin wrapper over the OS facility, and often
the OS terms a missing file an "error".

I might have chosen to implement a 'None' return if I had designed
open(), but I can't get too upset about raising an Exception as it
actually does.

What I want to know is why you're willing to assert that absence of a
clock of a particular configuration is an Exception, when that absence
clearly documented to be a common case? I don't find your analogies
to be plausible. They seem to come down to "sometimes in Python we've
made choices that impose extra work on some use cases, so we should
impose extra work on this use case too." But that surely isn't what
you mean.
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 [ In reply to ]
Cameron Simpson wrote:
> On 05Apr2012 08:50, Steven D'Aprano <steve@pearwood.info> wrote:
> | Although I don't like the get_clock() API, I don't think this argument against
> | it is a good one.
>
> Just to divert briefly; you said in another post you didn't like the API
> and (also/because?) it didn't help discoverability.
>
> My core objective was to allow users to query for clocks, and ideally
> enumerate and inspect all clocks. Without the caller having platform
> specific knowledge.

Clocks *are* platform specific -- not just in their availability, but also in
the fine details of their semantics and behaviour. I don't think we can or
should try to gloss over this. If people are making decisions about timers
without knowledge of what their platform supports, they're probably making
poor decisions. Even the venerable time.time() and time.clock() differ between
Linux and Windows.


> Allowing for the sake of discussion that this is desirable, what would
> you propose as an API instead of get_clock() (and its friend, get_clocks()
> for enumeration, that I should stuff into the code).

The old ways are the best. We don't have math.get_trig() and math.get_trigs()
functions for querying trigonometric functions, we just expose the functions
directly.

I think the way to enumerate and inspect all clocks is with the tried and true
Python introspection tools that people use on all other functions:

* use dir(time) to see a list of names available in the module
* use help(time) to read their help
* read the Fine Manual to find out more
* use try... except... to detect the existence of a clock

There's nothing special about clocks that needs anything more than this.

get_clock() looks like a factory function, but it actually isn't. It just
selects from a small number of pre-existing clocks. We should just expose
those pre-existing clocks directly. I don't see any advantage in adding that
extra level of indirection or the addition of all this complexity:

* a function get_clock() to select a clock
* a function get_clocks() to enumerate all the clocks
* another function for querying the properties of a clock

All those functions accomplish is to increase the complexity of the API, the
documentation and the implementation. It's one more special case for the user
to learn:

"To find out what functions are available, use dir(module), except for clocks,
where you have to use time.get_clocks()."

Blah.

Another problem with get_clock() -- it will be an attractive nuisance for the
sort of person who cares about symmetry and completeness. You will have a
steady trickle of "feature requests" from users who are surprised that not
every combination of features is supported. Out of the eight or sixteen or
thirty-two potential clocks that get_clock() tempts the user with, only three
or five will actually exist.

The only advantage of get_clock is that you don't need to know the *name* of a
platform clock in order to use it, you can describe it with a series of flags
or enums. But in practice, that's not an advantage, that's actually a
disadvantage. Consider:

"Which clock should I use for such-and-such a task, foo or bar?"

versus

"Which clock should I use for such-and-such a task, get_clock(spam, eggs,
cheese) or get_clock(ham, eggs, truffles)?"

The mere mechanics of talking about these clocks will suffer because they
aren't named.



--
Steven
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 (was: PEP 418: Add monotonic clock) [ In reply to ]
On Thu, Apr 5, 2012 at 21:57, Stephen J. Turnbull <stephen@xemacs.org> wrote:
> I might have chosen to implement a 'None' return if I had designed
> open(), but I can't get too upset about raising an Exception as it
> actually does.

One fundamental difference is that there are many reasons one might
fail to open a file. It may not exist. It may not have permissions
allowing the request. It may be locked. If open() returned None, this
information would have to be retrievable through another function.
However since it returns an exception, that information is already
wrapped up in the exception object, should you choose to catch it, and
likely to be logged otherwise.

In the case of the clocks, I'm assuming the only reason you would fail
to get a clock is because it isn't provided by hardware and/or OS. You
don't have to worry about transient scenarios on multi-user systems
where another user has locked the clock. Thus the exception cannot
tell you anything more than None tells you. (Of course, if my
assumption is wrong, I'm not sure whether my reasoning still applies.)

--
Michael Urman
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 [ In reply to ]
On 06Apr2012 20:25, Steven D'Aprano <steve@pearwood.info> wrote:
| Cameron Simpson wrote:
| > My core objective was to allow users to query for clocks, and ideally
| > enumerate and inspect all clocks. Without the caller having platform
| > specific knowledge.
|
| Clocks *are* platform specific -- not just in their availability, but also in
| the fine details of their semantics and behaviour. I don't think we can or
| should try to gloss over this.

This is why get_clock() returns a clock object, which can have metadata
exposing such details. Up to and including the name of the platform specific
library/system-call at its core.

The issue with monotonic() on its own is that the guarentees in the doco
will have to be fairly loose. That prevents the user learning about
"fine details of their semantics and behaviour". Glossing over this
stuff is exactly what offering _only_ a few genericly characterised
clock names (monotonic() et al) does.

| If people are making decisions about timers
| without knowledge of what their platform supports, they're probably making
| poor decisions. Even the venerable time.time() and time.clock() differ between
| Linux and Windows.

time.clock() does, as (you?) clearly demonstrated elsewhere.

time.time()? (Aside from precision?)

| > Allowing for the sake of discussion that this is desirable, what would
| > you propose as an API instead of get_clock() (and its friend, get_clocks()
| > for enumeration, that I should stuff into the code).
|
| The old ways are the best. We don't have math.get_trig() and math.get_trigs()
| functions for querying trigonometric functions, we just expose the functions
| directly.
|
| I think the way to enumerate and inspect all clocks is with the tried and true
| Python introspection tools that people use on all other functions:
|
| * use dir(time) to see a list of names available in the module

So, they see "monotonic". Does that tell them much about fine details?

| * use help(time) to read their help

Useful only to humans, not programs.

| * read the Fine Manual to find out more

Useful only to humans, not programs.

| * use try... except... to detect the existence of a clock

Useful only for a fixed list of defined name. Works fine for monotonic,
highres, steady or whatever. And I would be ok with the module
presenting these only where available and concealing them otherwise,
thus raising AttributeError. Or ImportError ("from time import
monotonic").

| There's nothing special about clocks that needs anything more than this.

This I think is false. In fact, I think your own statement at the start
about glossing over fine details goes against this.

If I ask for a highres clock, I might well care _how_ precise it was.

If I ask for a steady clock, I might well care how large its slews were.

If I ask for a monotonic clock, I might well want to know if it tracks
wall clock time (even if by magic) or elapsed system run time (eg time
that stops increasing if the system is suspended, whereas wallclocks do
not). Example: a wallclock is nice for log timestamps. A system run time
clock is nice for profiling. They're both monotonic in some domain.

| get_clock() looks like a factory function, but it actually isn't. It just
| selects from a small number of pre-existing clocks.

That number may still be a few. Victor's made it clear that Windows
has a choice of possible highres clocks, UNIX clock_getres() offers
several possible clock behaviours and an indication that a platform may
have several clocks embodying a subset of these, and may indeed offer
more clocks.

| We should just expose
| those pre-existing clocks directly.

But exposing them _purely_ _by_ _name_ means inventing names for every single
platform clock, and knowing those names per platform. time.clock() is a
fine example where the name tells you nearly nothing about the clock
behaviour. If the user cares about fine detail as you suggest they need
to know their platform and have _external_ knowledge of the platform
specifics; they can't inspect from inside the program.

| I don't see any advantage in adding that
| extra level of indirection or the addition of all this complexity:
| * a function get_clock() to select a clock
| * a function get_clocks() to enumerate all the clocks

These are only two functions because the next alternative seemed an
all_clocks= mode parameter, which changed the signature of the function
return.

Another alternative is the public lists-of-clocks.

The point it to be able to enumerate all available clocks for
consideration of their properties; get_clock() provides a simple way
to coarsely say "a clock like _this_" for the common instances of
"this".

| * another function for querying the properties of a clock

No, that's why you get a clock object back. You can examine it directly
for defined metadata names (epoch, precision, underlying-os-clock-name,
etc). In exactly the fashion you appear to want for the top level
offerings: by knowing the metadata property names.

| All those functions accomplish is to increase the complexity of the API, the
| documentation and the implementation. It's one more special case for the user
| to learn:
|
| "To find out what functions are available, use dir(module), except for clocks,
| where you have to use time.get_clocks()."

But dir(module) _will_ list monotonic et al anyway, and possibly matching
public clock list names. get_clock() is only for when you want to dig
around more flexibly.

| Another problem with get_clock() -- it will be an attractive nuisance for the
| sort of person who cares about symmetry and completeness. You will have a
| steady trickle of "feature requests" from users who are surprised that not
| every combination of features is supported. Out of the eight or sixteen or
| thirty-two potential clocks that get_clock() tempts the user with, only three
| or five will actually exist.

And the optional "clocklist" parameter addresses such feaping creaturism
by providing a hook for _other_ modules to offer a clock list. Such as a
list of syntheic clocks with cool (or insane:-) properties. Without
burdening the time module.

| The only advantage of get_clock is that you don't need to know the *name* of a
| platform clock in order to use it, you can describe it with a series of flags
| or enums. But in practice, that's not an advantage, that's actually a
| disadvantage. Consider:
|
| "Which clock should I use for such-and-such a task, foo or bar?"

What's your list of foo, bah? Again, I'm not talking about removing
monotonic et al. I'm talking about exposing the alternatives for when
the chosen-by-the-module monotonic doesn't fit.

| versus
| "Which clock should I use for such-and-such a task, get_clock(spam, eggs,
| cheese) or get_clock(ham, eggs, truffles)?"

One hopes the user knows the task. Then they can specify cheese or
truffles. Again, only if they feel they need to because the bare
monotonic et al don't fit, or was too vague.

| The mere mechanics of talking about these clocks will suffer because they
| aren't named.

But they _can_ be named! get_clock() is for when you don't know or care
their names, only their behaviours! And also for when an available clock
_wasn't_ one returned by the monotonic et al names.

Cheers,
--
Cameron Simpson <cs@zip.com.au> DoD#743
http://www.cskk.ezoshosting.com/cs/

I do not trust thee, Cage from Hell, / The reason why I cannot tell, /
But this I know, and know full well: / I do not trust thee, Cage from Hell.
- Leigh Ann Hussey, leighann@sybase.com, DoD#5913
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
Re: an alternative to embedding policy in PEP 418 [ In reply to ]
On 4/6/2012 4:11 PM, Cameron Simpson wrote:
> Another alternative is the public lists-of-clocks.

After watching this thread with amusement and frustration, amusement
because it is so big, and so many people have so many different
opinions, frustration, because it seems that few of the clocks that are
available are anywhere near ideal for any particular stated
characteristic, and because none of the APIs presented provide a way for
the user to specify the details of the characteristics of the desired
clock, I think this idea of a list-of-clocks sounds better and better.

Hopefully, for each system, the characteristics of each clock can be
discovered, and fully characterized in available metadata for the clock...

tick rate, or list of tick rates
maximum variation of tick rate
precision
maximum "helicopter drop" jump delta
monotonicity
frequency of rollover or None
base epoch value or None
behavior during system sleep, hibernate, suspend, shutdown, battery
failure, flood, wartime events, and acts of God. These last two may have
values that are long prose texts full of political or religious
rhetoric, such as the content of this thread :)
any other characteristics I forgot to mention

Of course, it is not clear that all of these characteristics can be
determined based on OS/Version; hardware vendors may have different
implementations.

There should be a way to add new clock objects to the list, given a set
of characteristics, and an API to retrieve them, at least by installing
a submodule that provides access to an additional clock.

1 2 3  View All