Re: [Python-ideas] Keyword only argument on function call

2018-09-10 Thread Steve Barnes


On 10/09/2018 22:00, Ethan Furman wrote:
> On 09/10/2018 12:52 PM, Chris Barker via Python-ideas wrote:
> 
>> I've spent this whole thread thinking: "who in the world is writing 
>> code with a lot of spam=spam arguments? If you are transferring that 
>> much state in a function call, maybe you should have a class that 
>> holds that state? Or pass in a **kwargs dict?
> 
>> So still looking for a compelling use-case
> 
> In my day job I spend a lot of time writing/customizing modules for a 
> framework called OpenERP (now Odoo*).  Those modules are all subclasses, 
> and most work will require updating at least a couple parent metheds -- 
> so most calls look something like:
> 
>    def a_method(self, cr, uid, ids, values, context=None):
>      ...
>      super(self, parent).a_method(cr, uid, ids, values, context=context)
> 
> Not a perfect example as these can all be positional, but it's the type 
> of code where this syntax would shine.
> 
> I think, however, that we shouldn't worry about a lead * to activate it, 
> just use a leading '=' and let it show up anywhere and it follows the 
> same semantics/restrictions as current positional vs keyword args:
> 
>    def example(filename, mode, spin, color, charge, orientation):
>    pass
> 
>    example('a name', 'ro', =spin, =color, charge=last, =orientation)
> 
> So +0 with the above proposal.
> 
> -- 
> ~Ethan~
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/

Couldn't just about all of the use cases mentioned so far be met in 
quite a neat manner by providing access to a method, or dictionary, 
called __params__ which would give access, as a dictionary, to the 
parameters as supplied in the call, (or filled in by the defaults).

If this was accessible externally, as fn.__defaults__ is then examples 
such as:

 >def a_method(self, cr, uid, ids, values, context=None):
 >  ...
 >  super(self, parent).a_method(cr, uid, ids, values, context=context)

would become:


 def a_method(self, cr, uid, ids, values, context=None):
   ...
   params = {k:v for k,v in __params__ if k in parent.a_method.keys()}
   # Possibly add some additional entries here!
   super(self, parent).a_method(**params)
-- 
Steve (Gadget) Barnes
Any opinions in this message are my personal opinions and do not reflect 
those of my employer.

---
This email has been checked for viruses by AVG.
https://www.avg.com

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] __iter__(), keys(), and the mapping protocol

2018-09-10 Thread Alex Walters
I can see custom mapping types where iterating the keys() would be trivial, but 
items() could be expensive.  I could use that as an argument, but I don't have 
to. The keys() method is part of the API, just like index() and count() are 
part of the sequence API.  To be treated like a mapping everywhere, python 
requires that you define* a keys() method, so why not use it?  I don't see 
anything wrong with python using "public" methods, in this context.


* If you use ABCs, then you don't need to define keys(), but that’s a tangent.

> -Original Message-
> From: Python-ideas  list=sdamon@python.org> On Behalf Of Elias Tarhini
> Sent: Monday, September 10, 2018 10:04 PM
> To: Python-Ideas 
> Subject: [Python-ideas] __iter__(), keys(), and the mapping protocol
> 
> This has been bouncing around in my head for a while regarding the requisite
> keys() method on mappings:
> 
> How come the ** unpacking operator, a built-in language feature, relies on a
> non-dunder to operate?
> 
> To me, I mean to say, requiring that classes implement keys() – a method
> whose name is totally undistinguished – in order to conform to the mapping
> protocol feels like a design running counter to Python's norm of using
> dunders for everything "hidden". I am not sure if it feels dirty to anybody
> else, however. Interestingly, the docs already say
> 
> that [f]or mappings, [__iter__()] should iterate over the keys of the
> container, but it of course is not enforced in any way at present.
> 
> 
> So, then — how about enforcing it? Should __iter__(), for the reasons
> above, replace the current purpose of keys() in mappings?
> 
> 
> I'm not properly equipped at the moment to mess around with CPython
> (sorry), but I assume at a minimum this would entail either replacing all
> instances of PyMapping_Keys() with PyObject_GetIter() or alternatively
> changing  PyMapping_Keys() to call the latter.
> 
> 
> Does it sound like a reasonable change overall?
> 
> 
> Eli

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] __iter__(), keys(), and the mapping protocol

2018-09-10 Thread Elias Tarhini
This has been bouncing around in my head for a while regarding the
requisite keys() method on mappings:

How come the ** unpacking operator, a built-in language feature, relies on
a non-dunder to operate?

To me, I mean to say, requiring that classes implement keys() – a method
whose name is totally undistinguished – in order to conform to the mapping
protocol feels like a design running counter to Python's norm of using
dunders for everything "hidden". I am not sure if it feels dirty to anybody
else, however. Interestingly, the docs already say

that *[f]or
mappings, [__iter__()] should iterate over the keys of the container*, but
it of course is not enforced in any way at present.

So, then — how about enforcing it? Should __iter__(), for the reasons
above, replace the current purpose of keys() in mappings?

I'm not properly equipped at the moment to mess around with CPython
(sorry), but I assume at a minimum this would entail either replacing all
instances of PyMapping_Keys() with PyObject_GetIter() or alternatively
changing  PyMapping_Keys() to call the latter.

Does it sound like a reasonable change overall?

Eli
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2018-09-10 Thread Abe Dillon
[Cameron Simpson]

> I've been writing quite a few functions lately where it is reasonable for
> a
> caller to want to pass arbitrary keyword arguments, but where I also want
> some
> additional parameters for control purposes.


I've run into this before and use the trailing '_' convention for names:

def update(self, where_, **column_vals): ...

Because such names are **probably** never going to show up. But, of course;
if such
a name were actually used for a column, it would be a fantastically hard
bug to find!

On Thu, Sep 6, 2018 at 11:01 PM Cameron Simpson  wrote:

> On 01Mar2017 21:25, Serhiy Storchaka  wrote:
> >On 28.02.17 23:17, Victor Stinner wrote:
> >>My question is: would it make sense to implement this feature in
> >>Python directly? If yes, what should be the syntax? Use "/" marker?
> >>Use the @positional() decorator?
> >
> >I'm strongly +1 for supporting positional-only parameters. The main
> >benefit to me is that this allows to declare functions that takes
> >arbitrary keyword arguments like Formatter.format() or
> >MutableMapping.update(). Now we can't use even the "self" parameter
> >and need to use a trick with parsing *args manually. This harms clearness
> and
> >performance.
>
> I was a mild +0.1 on this until I saw this argument; now I am +1 (unless
> there's some horrible unforseen performance penalty).
>
> I've been writing quite a few functions lately where it is reasonable for
> a
> caller to want to pass arbitrary keyword arguments, but where I also want
> some
> additional parameters for control purposes. The most recent example was
> database related: functions accepting arbitrary keyword arguments
> indicating
> column values.
>
> As a specific example, what I _want_ to write includes this method:
>
>   def update(self, where, **column_values):
>
> Now, because "where" happens to be an SQL keyword it is unlikely that
> there
> will be a column of that name, _if_ the database is human designed by an
> SQL
> person. I have other examples where picking a "safe" name is harder. I can
> even
> describe scenarios where "where" is plausible: supposing the the database
> is
> generated from some input data, perhaps supplied by a CSV file (worse, a
> CSV
> file that is an export of a human written spreadsheet with a "Where"
> column
> header).  That isn't really even made up: I've got functions whose purpose
> is
> to import such spreadsheet exports, making namedtuple subclasses
> automatically
> from the column headers.
>
> In many of these situations I've had recently positional-only arguments
> would
> have been very helpful. I even had to bugfix a function recently where a
> positional argument was being trouced by a keyword argument by a caller.
>
> Cheers,
> Cameron Simpson 
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Positional-only parameters

2018-09-10 Thread Abe Dillon
That looks great to me! I also think the '/' syntax looks fine and the pun
works. If part of the motivation for position-only arguments was better
performance and that motivation still holds water, then it makes sense to
allow Python to support that optimization, but I would be happy with just a
decorator too.

I definitely DON'T like the double-underscore. On top of all the other
complaints, I think it's more prone to break code. It's also more ugly than
'/' IMHO.

‪On Thu, Mar 2, 2017 at 5:10 AM ‫אלעזר‬‎  wrote:‬

> Here's a proof-of-concept for the decorator. It does not address the issue
> of passing aliases to positional arguments to **kwargs - I guess this
> requires changes in the CPython's core.
>
> (Sorry about the coloring, that's how it's pasted)
>
> from inspect import signature, Parameter
> from functools import wraps
>
>
> def positional_only(n):
> def wrap(f):
> s = signature(f)
> params = list(s.parameters.values())
> for i in range(n):
> if params[i].kind != Parameter.POSITIONAL_OR_KEYWORD:
> raise TypeError('{} has less than {} positional 
> arguments'.format(f.__name__, n))
> params[i] = params[i].replace(kind=Parameter.POSITIONAL_ONLY)
> f.__signature__ = s.replace(parameters=params)
> @wraps(f)
> def inner(*args, **kwargs):
> if len(args) < n:
> raise TypeError('{} takes at least {} positional 
> arguments'.format(f.__name__, n))
> return f(*args, **kwargs)
> return inner
> return wrap
>
>
> @positional_only(2)
> def f(a, b, c):
> print(a, b, c)
>
>
> help(f)
> # f(a, b, /, c, **kwargs)
>
> f(1, 2, c=2)
>
> # f(1, b=2, c=3)
> # TypeError: f takes at least 2 positional arguments
>
>
> @positional_only(3)
> def g(a, b, *, c):
> print(a, b, c)
>
> # TypeError: g has less than 3 positional arguments
>
> Elazar
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Python dialect that compiles into python

2018-09-10 Thread Abe Dillon
[Steven D'Aprano]

> It would be great for non-C coders to be able to prototype proposed
> syntax changes to get a feel for what works and what doesn't.


I think it would be great in general for the community to be able to try
out ideas and mull things over.

If there was something like a Python Feature Index (PyFI) and you could
install mods to the language,
it would allow people to try out ideas before rejecting them or
incorporating them into the language
(or putting them on hold until someone suggests a better implementation).

I could even see features that never make it into the language, but stick
around PyFI and get regular
maintenance because:
A) they're controversial changes that some love and some hate
B) they make things easier in some domain but otherwise don't warrant
adoption

It would have to be made clear from the start that Python can't guarantee
backward compatibility with
any mods, which should prevent excessive fragmentation (if you want your
code to be portable, don't
use mod).

On Fri, Sep 7, 2018 at 7:30 PM Steven D'Aprano  wrote:

> On Fri, Sep 07, 2018 at 11:57:50AM +, Robert Vanden Eynde wrote:
>
> > Many features on this list propose different syntax to python,
> > producing different python "dialects" that can statically be
> > transformed to python :
>
> [...]
> > Using a modified version of ast, it is relatively easy to modifiy the
> > syntax tree of a program to produce another program. So one could
> > compile the "python dialect" into regular python. The last example
> > with partially for example doesn't even need new syntax.
>
> [...]
> > Actually, I might start to write this lib, that looks fun.
>
> I encourage you to do so! It would be great for non-C coders to be able
> to prototype proposed syntax changes to get a feel for what works and
> what doesn't.
>
> There are already a few joke Python transpilers around, such as
> "Like, Python":
>
> https://jon.how/likepython/
>
> but I think this is a promising technique that could be used more to
> keep the core Python language simple while not *entirely* closing the
> door to people using domain-specific (or project-specific) syntax.
>
>
> --
> Steve
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-10 Thread Ethan Furman

On 09/10/2018 12:52 PM, Chris Barker via Python-ideas wrote:

I've spent this whole thread thinking: "who in the world is writing code 
with a lot of spam=spam arguments? If you are transferring that much 
state in a function call, maybe you should have a class that holds that 
state? Or pass in a **kwargs dict?



So still looking for a compelling use-case


In my day job I spend a lot of time writing/customizing modules for a 
framework called OpenERP (now Odoo*).  Those modules are all subclasses, 
and most work will require updating at least a couple parent metheds -- 
so most calls look something like:


  def a_method(self, cr, uid, ids, values, context=None):
...
super(self, parent).a_method(cr, uid, ids, values, context=context)

Not a perfect example as these can all be positional, but it's the type 
of code where this syntax would shine.


I think, however, that we shouldn't worry about a lead * to activate it, 
just use a leading '=' and let it show up anywhere and it follows the 
same semantics/restrictions as current positional vs keyword args:


  def example(filename, mode, spin, color, charge, orientation):
  pass

  example('a name', 'ro', =spin, =color, charge=last, =orientation)

So +0 with the above proposal.

--
~Ethan~
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-10 Thread Chris Barker via Python-ideas
On Sun, Sep 9, 2018 at 7:37 AM, Anders Hovmöller 
wrote:

I've spent this whole thread thinking: "who in the world is writing code
with a lot of spam=spam arguments? If you are transferring that much state
in a function call, maybe you should have a class that holds that state? Or
pass in a **kwargs dict?

Note: I write a lot of methods (mostly __init__) with a lot of keyword
parameters -- but they all tend have sensible defaults, and/or will have
many values specified by literals.

Then this:

> It would almost certainly become the strongly preferred way to do it for
> some cases like .format() and sending a context to a template renderer in
> web apps. But that’s because in those cases it is very important to match
> the names.


OK -- those are indeed good use cases, but:

for .format() -- that's why we now have f-strings -- done.

for templates -- are you really passing all that data in from a bunch of
variables?? as opposed to, say, a dict? That strikes me as getting code and
data confused (which is sometimes hard not to do...)

So still looking for a compelling use-case

-CHB

-- 

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR(206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115   (206) 526-6317   main reception

chris.bar...@noaa.gov
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-10 Thread Steven D'Aprano
On Mon, Sep 10, 2018 at 08:05:22AM +0200, Anders Hovmöller wrote:

> I just realized I have another question for you:

Is that a generic you or just me personally? :-)

> If you had to chose which one would you prefer:
> 
> f(*, a b, c)
> 
> or:
> 
> f(=a, =b, =c)
> 
> ?

I can't say I particularly like either syntax, but if I had a gun 
pointed at my head and had to choose one, I'd *probably* prefer 
something like this:

open("myfile.txt", 'r', =buffering, =encoding, =errors, 
 newline='\r', =closefd, opener=get_opener())

over this:

open("myfile.txt", 'r', *, buffering, encoding, errors, 
 newline='\r', closefd, opener=get_opener())


In the second case, the * is too easy to miss, leaving us with what 
looks like a confusing mix of positional and keyword arguments.

Hmmm... a thought comes to mind...

Suppose we had a wild-card symbol that simply told the parser to use 
the same string as that on the left hand side of the = sign, that might 
be promising. For the sake of illustration, I'm going to use the Unicode 
Snowman symbol, but that's just a place-holder.

☃ copies the token from the left hand side of the = to the right
hand side. It is a syntax error if it doesn't follow an = sign.

Then we could be (slightly) concise AND explicit:

open("myfile.txt", 'r', buffering=☃, encoding=☃, errors=☃, 
 newline='\r', closefd=☃, opener=get_opener())

would expand to:

open("myfile.txt", 'r', buffering=buffering, encoding=encoding, 
 errors=errors, newline='\r', closefd=closefd, opener=get_opener())

But honestly, this feels Perlish to me, or something that belongs in a 
personal pre-processor rather than the language.

(Maybe we should embrace the concept of a Python pre-processor?)


> I know you’re clearly against the entire idea but it seems we should 
> prefer the least disliked alternative in such a scenario.

I accept this is a pain point for some people and some code bases.

I'm not convinced it is painful enough to need a language-wide syntactic 
solution (but I don't have any better solution except "refactor until 
the pain goes away"), or that the benefit outweighs the real and 
potential costs. I wouldn't quite describe it as being "against the 
entire idea". It's not that I'm against the very idea of improving 
parameter handling in Python. I just don't think this is the way.



-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Pre-conditions and post-conditions

2018-09-10 Thread Marko Ristin-Kaufmann
Hi,

I implemented the inheritance via meta classes and function and class
attributes for pre/postconditions and invariants, respectively. Unless I
missed something, this is as far as we can go without the proper language
support with a library based on decorators:
https://github.com/Parquery/icontract (version 1.5.0)

 Note that it is actually a complete implementation of design-by-contract
that supports both weakening of the preconditions and strengthening of the
postconditions and invariants.

Could you please have a look and let me know what you think about the
current implementation?

Once we are sure that there is nothing obvious missing, I'd like to move
forward and discuss whether we could add this library (or rewrite it) into
the standard Python libraries and what needs to be all fixed till to make
it that far.

Cheers,
Marko

On Sat, 8 Sep 2018 at 21:34, Jonathan Fine  wrote:

> Michel Desmoulin wrote:
>
> > Isn't the purpose of "assert" to be able to do design by contract ?
> >
> > assert test, "error message is the test fail"
> >
> > I mean, you just write your test, dev get a feedback on problems, and
> > prod can remove all assert using -o.
> >
> > What more do you need ?
>
> Good question. My opinion is that assert statements are good. I like them.
>
> But wait, more is possible. Here are some ideas.
>
> 1. Checking the return value (or exception). This is a post-condition.
>
> 2. Checking return value, knowing the input values. This is a more
> sophisticated post-condition.
>
> 3. Adding checks around an untrusted function - possibly third party,
> possibly written in C.
>
> 4. Selective turning on and off of checking.
>
> The last two, selective checks around untrusted functions, I find
> particularly interesting.
>
> Suppose you have a solid, trusted, well-tested and reliable system.
> And you add, or change, a function called wibble(). In this situation,
> errors are most likely to be in wibble(), or in the interface to
> wibble().
>
> So which checks are most valuable? I suggest the answer is
>
> 1. Checks internal to wibble.
>
> 2. Pre-conditions and post-conditions for wibble
>
> 3. Pre-conditions for any function called by wibble.
>
> Suppose wibble calls wobble. We should certainly have the system check
> wobble's preconditions, in this situation. But we don't need wobble to
> run checks all the time. Only when the immediate caller is wibble.
>
> I think assertions and design-by-contract point in similar directions.
> But design-by-contract takes you further, and is I suspect more
> valuable when the system being built is large.
>
> Thank you, Michel, for your good question.
>
> --
> Jonathan
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Add Unicode-aware str.reverse() function?

2018-09-10 Thread Paddy3118


On Sunday, 9 September 2018 06:30:19 UTC+1, Steven D'Aprano wrote:
>
> On Sat, Sep 08, 2018 at 04:33:07AM -0700, Paddy3118 wrote: 
> > I wrote a blog post 
> > <
> http://paddy3118.blogspot.com/2009/07/case-of-disappearing-over-bar.html>nearly
>  
>
> > a decade ago on extending a Rosetta Code task example 
> > to handle the correct 
> > reversal of strings with combining characters. 
>
> I wouldn't care too much about a dedicated "reverse" method that handled 
> combining characters. I think that's just a special case of iterating 
> over graphemes. If we can iterate over graphemes, then reversing because 
> trivial: 
>
> ''.join(reversed(mystring.graphemes())) 
>
> The Unicode Consortium offer an algorithm for identifying grapheme 
> clusters in text strings, and there's at least three requests on the 
> tracker (one closed, two open). 
>
> https://bugs.python.org/issue30717 
>
> https://bugs.python.org/issue18406 
>  
> https://bugs.python.org/issue12733 
>

Well that ends this idea!

Thanks Steve :-)

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Keyword only argument on function call

2018-09-10 Thread Anders Hovmöller
I just realized I have another question for you:

If you had to chose which one would you prefer:

f(*, a b, c)

or:

f(=a, =b, =c)

?

I know you’re clearly against the entire idea but it seems we should prefer the 
least disliked alternative in such a scenario. 
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/