[Python-ideas] Re: Cartesian Product on `__mul__`

2019-07-30 Thread Thomas Jollans
On 25/07/2019 19.41, Andrew Barnert via Python-ideas wrote:
> On Jul 25, 2019, at 09:46, Batuhan Taskaya  wrote:
>> I think it looks very fine when you type {1, 2, 3} * {"a", "b", "c"} and get 
>> set(itertools.product({1, 2, 3}, {"a", "b", "c"})). So i am proposing set 
>> multiplication implementation as cartesian product. 
> I think it might make more sense to reopen the discussion of using @ for 
> cartesian product for all containers, for a few reasons.
>
>  * The * operator means repeat on lists, tuples, and strings. While there are 
> already some operator differences between sets and other containers, but it’s 
> generally the types supporting different operators (like sets having | and &, 
> and not having +) rather than giving different meanings to the same 
> operators. Plus, tuples are frequently used for small things that are 
> conceptually sets or set-like; this is even enshrined in APIs like 
> str.endswith and isinstance.
>
>  * (Ordered) Cartesian product for lists, tuples, iterators, etc. makes just 
> as much sense even when they’re not being used as pseudo-sets, ordered sets, 
> or multisets, and might even be more common in code in practice (which is 
> presumably why there’s a function for that in the stdlib). So, why only allow 
> it for sets?
>
>  * Cartesian product feels more like matrix multiplication than like scalar 
> or elementwise multiplication or repetition, doesn’t it?

Adding @ to sets for Cartesian products *might* be reasonable, but
giving @ a meaning other than matrix multiplication for ordered
collections (lists, tuples) sounds like a terrible idea that will only
cause confusion.



>
>  * Adding @ to the builtin containers was already raised during the @ 
> discussion and tabled for the future. I believe this is because the NumPy 
> community wanted the proposal to be as minimal as possible so they could be 
> sure of getting it, and get it ASAP, not because anyone had or anticipated 
> objections beyond “is it common enough of a need to be worth it?”
>
> I don’t think this discussion would need to include other ideas deferred at 
> the same time, like @ for composition on functions. (Although @ on iterators 
> might be worth bringing up, if only to reject it. We don’t allow + between 
> arbitrary iterables defaulting to chain but meaning type(lhs)(chain(…)) on 
> some types, so why do the equivalent with @?)
> ___
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at 
> https://mail.python.org/archives/list/python-ideas@python.org/message/LR5PQMLLTBTARLK4NLUYSPIWFRTWJHLA/
> Code of Conduct: http://python.org/psf/codeofconduct/

___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/VG66TRIL2XYRDDAJKAVMVSQ3CWQH5522/
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Support localization of unicode descriptions

2019-02-25 Thread Thomas Jollans
On 10/07/2018 23.20, David Mertz wrote:
> The problem with non-canonical translations of the Unicode character
> names is that there is not one unique possible rendering into language
> X. Equally, I could find synonyms in general English for the names, but
> one would be official, the others at best informally clarifying.

Let's not forget that some official names of unicode symbols are either
misleading or entirely wrong, but cannot be changed.

See e.g. https://www.unicode.org/notes/tn27/tn27-4.html


> For informational purposes I think it's great to have a third party
> project to find out "Unicode character named 'Something In English' is
> roughly translated as  in your native language." But it's hard
> to see how an unofficial loose cross-language dictionary should be party
> of the standard library.
> 
> On Tue, Jul 10, 2018, 5:11 PM Terry Reedy  > wrote:
> 
> On 7/10/2018 4:45 AM, Pander wrote:
> 
> > This is a third party initiative. The translations are contributed by
> > volunteers. I have talked with Python core developers and they
> suggested
> > to post this here, as it is for them out of scope for Python std lib.
> 
> Python-ideas list is for discussion of python and the stdlib library.
> This is not a place for prolonged discussion of pypi projects.
> It *is* a place to discuss adding a hook that can be used to access
> translations.
> 
> There are both official doc translations, accessible from the official
> doc pages, and others that are independent.  The official ones, at
> least, are discussed on the doc-sig list
> https://mail.python.org/mailman/listinfo/doc-sig
> There are currently 7 languages and coordinators listed at
> https://devguide.python.org/experts/#documentation-translations
> 4 have progressed far enough to be listed in the drop-down box on
> https://docs.python.org/3/
> 
> I should think that these people should be asked if they want to be
> involved with unicode description translations.  They should certainly
> have some helpful advice.
> 
> The description vocabulary is rather restricted, so a word translation
> dictionary should be pretty easy.  For at least for some languages, it
> should be possible to generate the 20 description translations from
> this. The main issues are word order and language-dependent 'word'
> units.  Hence, the three English words "LATIN SMALL LETTER" become two
> words in German, 'LATEINISCHER KLEINBUCHSTABE', versus three words in
> Spanish, but in reverse order, 'LETRA PEQUEÑA LATINA'.  It is possible
> that the doc translators already uses translation software that deal
> with these issues.
> 
> -- 
> Terry Jan Reedy
___
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] Is this PEP-able? "with" statement inside genexps / list comprehensions

2018-08-08 Thread Thomas Jollans
On 30/07/18 21:15, Rudy Matela wrote:
> Hello,
> 
> Do you think it would be nice to allow with statements inside genexps or
> list comprehensions?  The functions __enter__ and __exit__ would be
> automatically called as iterables are traversed.  I am thinking of
> drafting a PEP about this.  Examples:
> 
> 
> This 
> 
>   g = (f.read() for fn in filenames with open(fn) as f)
> 
> would be equivalent to the following use of a generator function:
> 
>   def __gen():
>   for fn in filenames:
>   with open(fn) as f:
>   yield f.read()
>   g = __gen()


To sail around Oscar's concern, this should rather be

def __gen():
for fn in filenames:
with open(fn) as f:
_v = f.read()
yield _v

But in this case I think it'd be clearer to make it an expression rather
than a generator expression term:

g = (f.read() with open(fn) as f for fn in filenames)

where

_ = f.read() with open(fn) as f

is equivalent to

with open(fn) as f:
_ = f.read()

Currently possibly (if silly) alternative:

from functools import wraps

class with_one_use:
def __init__(self, context):
self.__context = context

def __getattr__(self, name):
exc1 = False
obj = self.__context.__enter__()
try:
temp = getattr(obj, name)
except:
exc1 = True
if not self.__context.__exit__(*sys.exc_info()):
raise
else:
if callable(temp):
@wraps(temp)
def f(*args, **kwargs):
exc2 = False
try:
return temp(*args, **kwargs)
except:
exc2 = True
if not self.__context.__exit__(*sys.exc_info()):
raise
finally:
if not exc2:
self.__context.__exit__(None, None, None)
exc1 = True
return f
else:
return temp
finally:
if not exc1:
self.__context.__exit__(None, None, None)


g = (with_one_use(open(fn)).read() for fn in filenames)


-- Thomas

> 
> 
> This
> 
>   list = [f.read() for fn in filenames with open(fn) as f]
> 
> would be equivalent to the following:
> 
>   list = []
>   for fn in filenames:
>   with open(fn) as f:
>   list.append(f.read())
> 
> --
> Rudy
> ___
> 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] Change repr of collections.OrderedDict to be more dict-like

2018-07-27 Thread Thomas Jollans

On 27/07/18 08:06, Robert Vanden Eynde wrote:
Thanks for your response, I want to print/repr an OrderedDict() 
without relying on the fact that "dict are ordered" ie. I want a 
solution < python 3.7.
Currently, if I do repr( OrderedDict([(1,2),(3,4)]) ), I get the 
string "OrderedDict([(1,2),(3,4)])", I'd like a function that would 
return the string "{1: 2, 3: 4}" in the correct order.
If I do repr(dict( OrderedDict([(1,2),(3,4)]) )) I get "{1: 2, 3: 4}" 
because dict are ordered since python 3.7.
And for pprint, currently pformat( OrderedDict([(1,2),(3,4)]) ) gives 
the string 'OrderedDict([(1, 2), (3, 4)])' (and adds \n for bigger dict).
I could do pprint(dict( OrderedDict([(1,2),(3,4)]) )) but again that 
relies on python 3.7 behavior.
I'm wondering if there exists an easy way to code this "order 
preserving repr and pprint/pformat".


It's a fairly non-standard thing to do as you're not representing the 
ordered dict itself, but it's easy enough...


>>> od = OrderedDict([('a', 1), ('b', 2)])
>>> '{%s}' % ', '.join('{!r}: {!r}'.format(k, v) for (k, v) in  od.items())
"{'a': 1, 'b': 2}"
>>>

It's a bit more work if you want pretty-printing.

And there's always json.



Le ven. 27 juil. 2018 à 07:58, Steven D'Aprano > a écrit :


On Fri, Jul 27, 2018 at 05:30:35AM +, Robert Vanden Eynde wrote:

> Currently, what's the best way to implement a function
> f(OrderedDict([(1,2),(3,4)])) == '{1: 2, 3: 4}', works for all
> possible types, and also availaible for pprint with nice indent?

I don't understand the question, and I especially don't understand
the
"all possible types" part. Do you actually mean *all* possible types,
like int, float, str, MyClassThatDoesSomethingWeird?

But guessing (possibly incorrectly) what you want:

py> from collections import OrderedDict
py> od = OrderedDict([(1,2),(3,4)])
py> od == {1:2, 3: 4}
True

If efficiency is no concern, then the simplest way to get
something that
has a dict repr from an OrderedDict is to use a dict:

py> dict(od)
{1: 2, 3: 4}

This also works as OrderedDict is a subclass of dict, and should
avoid
the cost of building an entire dict:

py> dict.__repr__(od)
'{1: 2, 3: 4}'


> If I
> could set a parameter in ipython or python repl that would print
that,
> that would already be very useful.

See sys.displayhook.



-- 
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/




___
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] PEP 505: None-aware operators

2018-07-23 Thread Thomas Jollans
On 24/07/18 00:39, Chris Angelico wrote:
> On Tue, Jul 24, 2018 at 8:22 AM, Thomas Jollans  wrote:
>> On 18/07/18 19:43, Steve Dower wrote:
>>> When a ``None``-aware operator is present, the left-to-right evaluation
>>> may be
>>> short-circuited. For example, ``await a?.b(c).d?[e]`` is evaluated::
>>>
>>> _v = a
>>> if _v is not None:
>>> _v = _v.b
>>> _v = _v(c)
>>> _v = _v.d
>>> if _v is not None:
>>> _v = _v[e]
>>> await _v
>>
>> ## NB I only skimmed most of this thread after reading the PEP, so I ##
>> ##apologize if this has been discussed before and I missed it.   ##
>>
>> I quite like the general idea, but I'm nervous about a rather
>> fundamental aspect: This adds a special case in which you can't add
>> parentheses to an expression involving a chain of operators to make
>> precedence and evaluation order clear.
>>
>> To use your example,
>> a ?? 2 ** b ?? 3   ===  (a ?? 2) ** (b ?? 3) # fine
>>
>> In the present day,
>> a or 2 + 3 * c()   ===   a or (2 + (3 * (c(
>>
>> a.b(c).d[e]   ===   (((a.b)(c)).d)[e] # silly, but true.
>>
>> Short-circuiting doesn't break this. With and and or, the expression
>> that's short-circuited away is a self-contained expression in imagined
>> (or actual) parentheses.
> 
> What about:
> 
> 5 < x < 10
> 
> Can you add parentheses to that to "make precedence and evaluation order 
> clear"?


Well, no.

TJ wrote:
> [...] becomes one single, long, atomic expression,
> just like a comparison chain. [...]
  

This does leave the question,

> Is introducing the idea of an "attribute reference, call and
> subscription" chain worth it?



___
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] PEP 505: None-aware operators

2018-07-23 Thread Thomas Jollans
On 18/07/18 19:43, Steve Dower wrote:
> When a ``None``-aware operator is present, the left-to-right evaluation
> may be
> short-circuited. For example, ``await a?.b(c).d?[e]`` is evaluated::
> 
>     _v = a
>     if _v is not None:
>     _v = _v.b
>     _v = _v(c)
>     _v = _v.d
>     if _v is not None:
>     _v = _v[e]
>     await _v

## NB I only skimmed most of this thread after reading the PEP, so I ##
##apologize if this has been discussed before and I missed it.   ##

I quite like the general idea, but I'm nervous about a rather
fundamental aspect: This adds a special case in which you can't add
parentheses to an expression involving a chain of operators to make
precedence and evaluation order clear.

To use your example,
a ?? 2 ** b ?? 3   ===  (a ?? 2) ** (b ?? 3) # fine

In the present day,
a or 2 + 3 * c()   ===   a or (2 + (3 * (c(

a.b(c).d[e]   ===   (((a.b)(c)).d)[e] # silly, but true.

Short-circuiting doesn't break this. With and and or, the expression
that's short-circuited away is a self-contained expression in imagined
(or actual) parentheses.

With this ?. operator, the chain a?.b(c).d?[e] can no longer be broken
into sub-expressions, but becomes one single, long, atomic expression,
just like a comparison chain. If I try:

(a?.b)(c).d?[e] # TypeError: 'NoneType' object is not callable
a?.(b(c).d?[e]) # SyntaxError, and illogical

Also, where does this end? if a is None, is (a?.b,c()) equal to None or
(None, c())? Presumably the latter because of operator precedence, but
still.

Is introducing the idea of an "attribute reference, call and
subscription" chain worth it?

This could be fixed by adding a maybe-call ?( operator, which would allow

a?.b?(C())?.d?[E()]
   ===
a?.b)
?( C() ))
 ?.d)
   ?[ E() ])

_v = a
_v = _v.b if _v is not None else None
_v = _v(C()) if _v is not None else None
_v = _v.d if _v is not None else None
_v = _v[E()] if _v is not None else None

with None falling all the way through, and the calls to C() and E()
being short-circuited out.

Of course you need either attribute-call-subscription chains or ‘?()’
maybe-calls for ‘?.’ to be worthwhile at all, since otherwise you can't
write None-aware method calls.

Aside:  other languages cited
  From a quick look at the C# docs linked in the PEP [1], I'm guessing
  that C# allows A?.B?.C?.Do(E), but does not allow A?.B?.C.Do(E). Does
  anybody know? Obviously method calls work differently in C# than in
  Python.

  Dart? I dunno. The docs aren't as thorough.


Am I missing something?


Cheers
Thomas


[1]
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators

___
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] Adding Python interpreter info to "pip install"

2018-07-20 Thread Thomas Jollans
On 20/07/18 05:10, Al Sweigart wrote:
> Sorry, I meant "pip list", rather than "pip info".
> 
> I thought about the fact that "pip --version" provides this info, but 1)
> it provides the location of pip, not the python interpreter it installs
> packages for and 2) it would be an additional step for the
> question-asker to go through after posting the output of "pip install".

If the extra line of output was something like

This is $(pip --version)

that would be more consistent, and provide enough information.

> 
> It would be nice to display output that the question-asker can compare
> directly with the output of "which python". And I'd like to shorten the
> potential amount of back-and-forth before the helper can get the
> information they need.
> 
> Additionally, while they could always just run "python -m pip install
> spam" but most tutorials tell them to run pip directly, so I still see
> the need for this.
> 
> 
> On Thu, Jul 19, 2018 at 5:50 PM, Chris Angelico  > wrote:
> 
> On Fri, Jul 20, 2018 at 10:45 AM, Al Sweigart  > wrote:
> > The goal of this idea is to make it easier to find out when
> someone has
> > installed packages for the wrong python installation. I'm coming
> across
> > quite a few StackOverflow posts and emails where beginners are
> using pip to
> > install a package, but then finding they can't import it because
> they have
> > multiple python installations and used the wrong pip.
> >
> > For example, this guy has this problem:
> >
> 
> https://stackoverflow.com/questions/37662012/which-pip-is-with-which-python
> 
> 
> >
> > I'd propose adding a simple line to the output of "pip install"
> that changes
> > this:
> >
> > user@user:~$ pip3 install pyperclip
> > Collecting pyperclip
> > Installing collected packages: pyperclip
> > Successfully installed pyperclip-1.6.2
> >
> > ...to something like this:
> >
> > user@user:~$ pip3 install pyperclip
> > Running pip for /usr/bin/python3
> > Collecting pyperclip
> > Installing collected packages: pyperclip
> > Successfully installed pyperclip-1.6.2
> >
> > This way, when they copy/paste their output to StackOverflow, it'll be
> > somewhat more obvious to their helper that they used pip for the wrong
> > python installation.
> >
> > This info would also be useful for the output of "pip info", but
> that would
> > break scripts that reads that output.
> >
> > Any thoughts?
> 
> You can get some very useful information from "pip3 --version". As
> well as pip's own version, it tells you the version of Python that
> it's running under, AND what directory it's being run from. If you
> want to request that similar info be added to other commands, I would
> strongly recommend lifting the exact format of --version and using
> that.
> 
> (I'm not sure what "pip info" is, btw. My pip doesn't seem to have
> that.)
> 
> ChrisA
> ___
> 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/
> 

___
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] Looking for input to help with the pip situation

2017-11-07 Thread Thomas Jollans
On 2017-11-06 19:04, Michel Desmoulin wrote:
> 
>> I don't see anything particularly bogging here.
>> It's always like this when you have multiple versions of the same
>> software on the system. There's only one PATH, after all.
>>
>> Heck, *the mere fact that Python allows to work like this is already a
>> huge leap forward.* **Doing this cross-platform with exactly the same
>> steps is something few could believe was even possible a couple of years
>> ago!**
> 
> I agree.
> 
>>
>> To simplify things with Python, i do the following:
>> * use the system's Python whenever possible
> 
> So python 2.7 on mac and some linux or none for windows...
> 
>> * if using something else, only install the one version/environment that
>> I'm using day-to-day and add it to PATH (system's if safe & convenient,
>> personal otherwise)
>> * prefer the system's/environment's package manager to pip to install
>> 3rd-party modules, too, if there is one.
> 
> We can't solve the situation perfectly, but we can unify a bit. E.G:
> 
> - provide the "py" command on all OSes to avoid the various naming and
> aliases of python
> - promote it in documentation
> - promote the use of py -x.x -m pip instead of the myriads of alternatives

I'm sure there's a reason why these acrobatics are required on Windows,
but on other OS's separate "python3", "python3.6", "python2",
"python2.7" and "python" executables/symlinks all in the PATH work
perfectly fine.

As Ivan said earlier, perhaps the Windows installers should provide a
"python3" executable, so "python3 -m pip" works everywhere.

I normally use "pip2" and "pip3", but those aren't available everywhere,
and may be hard to support properly.


> - provide an empty pip and venv module. If they are not here, py -m pip
> says "your plateform doesn't provide pip by default, please do x" to
> install it. With "" being plateform specific.

Isn't pip installed by default on Windows and OSX? On Linux some
distribution will probably do something unexpected and mess up your
grand plan.

> - check "add python executable to system path" on the windows installer
> once by defaut

I like this, but I have a suspicion that this is rather unorthodox.


-- 
Thomas Jollans
___
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] Looking for input to help with the pip situation

2017-11-07 Thread Thomas Jollans
On 2017-11-06 23:53, Ivan Pozdeev via Python-ideas wrote:
> On 07.11.2017 1:48, Chris Barker wrote:
>> On Mon, Nov 6, 2017 at 9:52 AM, Michel Desmoulin
>> > wrote:
>>
>> I know and you still:
>>
>> - have to use py -m on windows, python3 linux, python in virtualenv...
>>
>>
>> can't you use python3 -m pip install .
>>
>> everywhere?
> You can't. Windows versions don't create versioned executables. Got
> bitten with this myself.

Once you're worked around that in the first place (lesson: "this is how
you start Python"), then figuring out whether you need "python -m pip"
or "python3 -m pip" shouldn't be a big deal.

Still the fact that the way you call Python is different on different
platforms is rather unfortunate.

-- Thomas

___
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] Composition over Inheritance

2017-10-30 Thread Thomas Jollans
On 29/10/17 19:25, Soni L. wrote:
> 
> 
> On 2017-10-29 02:57 PM, Brendan Barnwell wrote:
>> On 2017-10-29 04:44, Soni L. wrote:
>>> And this is how you miss the whole point of being able to dynamically
>>> add/remove arbitrary components on objects you didn't create, at
>>> runtime.
>>>
>>> Someone gave me this code and told me it explains what I'm trying to do:
>>> https://repl.it/NYCF/3
>>>
>>> class T:
>>>  pass
>>>
>>> class C:
>>>  pass
>>>
>>> c = C()
>>>
>>> #c.[T] = 1
>>> c.__dict__[T] = 1
>>
>> Again, can you please explain why you want to write c.[T]? What do
>> you intend that to *do*?  Your commented line seems to indicate you
>> want it to do what `c.__dict__[T]` does, but you can already do that
>> with `setattr(c, T, 1)`.  Or you can just give c an attribute that's a
>> dict, but has an easier-to-type name than __dict__, so you can do
>> `c.mydict[T]`.  What is the specific advantage of `c.[T]` over these
>> existing solutions?
>>
> 
> Hmm... Why can't we just allow empty identifiers, and set a default
> handler for empty identifiers that implements the proposed ECS?

It sounds to me like the general shape of what you're proposing is
already entirely possible, just without the idiosyncratic syntax. You
could write a library that adds support for your components using some
other syntax without any additional language support.

I don't know, something like this should be doable:

@componentlib.has_components
class Car:
# ...

class Engine(componentlib.Component): # might have to be a metaclass?
def stall(self, car):
raise UnpleasantNoise()
# ...

car = Car()
car.engine = Engine()
car.engine.stall()
# and so on.

If you prefer square brackets, you can implement it with __getitem__
syntax instead of __getattr__ syntax.

The point is: not only does your proposal not *need* additional language
support; I'm not at all convinced that it would benefit from additional
language support.

> 
> But the basic idea is to indicate something at the call site, namely
> that T is a contract and the object returned should respect that
> contract and any function calls should pass the original object as an
> argument. (I personally don't like how Python treats o.m() (has self)
> the same as o.f() (no self) syntax-wise, either.)
> ___
> 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] Composition over Inheritance

2017-10-28 Thread Thomas Jollans
On 28/10/17 14:19, Soni L. wrote:
> 
> 
> On 2017-10-28 09:51 AM, Steven D'Aprano wrote:
>> On Sat, Oct 28, 2017 at 09:09:30AM -0200, Soni L. wrote:
>>> As recent threads indicate, composition may sometimes be better than
>>> inheritance. And so I'd like to propose composition as a built-in
>>> feature.
>>>
>>> My idea is syntax of the form o.[c].m(), where o is an object, c is a
>>> component, m is a method.
>> How is that different from o.c.m() which works today?
>>
>> My understanding of composition is simply setting an attribute of your
>> instance to the component, then calling methods on the attribute. How
>> does that differ from what you are describing?
>>
>> Instead of the classic multiple-inheritence:
>>
>>
>> class Car(Engine, AcceleratorPedal, GasTank, ...):
>>  pass
>>
>> which requires each superclass to be designed to work with each other
>>
>> (e.g. you can't have both EntertainmentSystem.start() and
>> Ignition.start(), unless you want the ignition to automatically turn on
>> when the entertainment system does)
>>
>> we can instead use composition and delegation:
>>
>> class Car:
>>  def __init__(self):
>>  self.engine = Engine()
>>  self.accelerator = AcceleratorPedal()
>>  ...
>>
>>  def start(self):
>>  # Delegate to the ignition component.
>>  self.ignition.start()
>>
>>
>> etc. Obviously this is just a very loose sketch, don't take it too
>> literally. Is this the sort of thing you are talking about?
> 
> So how do you call car.ignition.start() from car.key.turn()?

self.car.ignition.start() of course.

If the key has to do something involving the car, it has to know about
the car, so tell it about the car:

class Car:
def __init__(self):
self.engine = Engine()
self.accelerator = AcceleratorPedal(self.engine)
self.ignition = Ignition(self)
self.key = Key(self)
# and so on.


FWIW I haven't the faintest idea what you're talking about. Please
provide an example that shows how you might create a "component" and use
it. Ideally, comparing it with an example of how you would currently so
the same thing in Python.



> 
>>
>>
>>> I am not sure how you'd set components, or test for components,
>> If you don't know how to set components, or test for them, what do you
>> know how to do with components?
>>
>> And how are components different from attributes?
> 
> They're more like conflict-free interfaces, and in this specific case
> they're designed with duck typing in mind. (You can dynamically add and
> remove components, and use whatever you want as the component. You
> cannot do that with inheritance.)
> 
>>
>>
>>> but I don't think it makes sense to be able to do o.[c][x] or
>>> x=o.[c], because
>>> those break the idea of automatically passing the object as an argument
>>> (unless we create whole wrapper objects every time the syntax is used,
>>> and that's a bit ew. also how would you handle o.[c1].[c2] ?).
>> I'm afraid I do not understand what you are talking about here.
>>
>> If might help if you give a concrete example, with meaningful names. It
>> would help even better if you can contrast the way we do composition now
>> with the way you think we should do it.
>>
>> I'm afraid that at the moment I'm parsing your post as:
>>
>> "composition is cool, we should use it; and o.[c].m() is cool syntax, we
>> should use it for composition; I'll leave the details to others".
> 
> Again, how do you call car.ignition.start() from car.key.turn()?
> 
>>
>>
>>> Thus I think o.[c].m() should be syntax sugar for o[c].m(o), with o
>>> being evaluated only once,
>> I don't see why you're using __getitem__ instead of attribute access;
>> nor do I understand why m gets o as argument instead of c.
>>
>> Wait... is this something to do with Lieberman-style delegation?
>>
>> http://web.media.mit.edu/~lieber/Lieberary/OOP/Delegation/Delegation.html
>>
>> http://code.activestate.com/recipes/519639-true-lieberman-style-delegation-in-python/
>>
>>
> 
> TL;DR. But no, it's not some form of delegation.
> 
> It still gets `self` (which is whatever is in o[c] - which may be c
> itself, or an arbitrary object that fulfills the contract defined by c),
> but also gets `o` in addition to `self`. (Unless it's a plain function,
> in which case it gets no `self`.)
> 
>>> as that solves a lot of current issues
>>> relating to inheritance while introducing very few issues relating to
>>> python's "everything is separate" (e.g. __get__ vs __getattr__)
>>> policy.This also makes setting components and testing for components
>>> fairly trivial, and completely avoids the issues mentioned above by
>>> making their syntax illegal.
>> Above you said that you don't know how to set and test for components,
>> now you say that doing so is trivial. Which is it?
> 
> If you pay closer attention, you'll notice the two different paragraphs
> talk about two different syntaxes.
> 
> - o.[c] as a standalone syntax element, allowing things 

Re: [Python-ideas] Dollar operator suggestion

2017-10-26 Thread Thomas Jollans
On 2017-10-26 13:06, Yan Pas wrote:
> I've looked up this feature in haskell. Dollar sign operator is used to
> avoid parentheses.
> 
> Rationalle:
> Python tends to use functions instead of methods ( e.g.len([1,2,3])
> instead of [1,2,3].len() ). Sometimes the expression inside parentheses
> may become big  and using a lot of parentheses may tend to bad
> readability. I suggest the following syntax:
> 
> len $ [1,2,3]

I see absolutely no benefit adding this syntax when we already have a
perfectly good function calling syntax.

> 
> Functions map be also  chained:
> 
> len $ list $ map(...)

Function composition has been discussed at length in the past, e.g.
https://mail.python.org/pipermail/python-ideas/2015-May/thread.html#33287

I'd like to highlight one key message:

https://mail.python.org/pipermail/python-ideas/2015-May/033491.html

Guido van Rossum wrote (May 11, 2015):
> As long as I'm "in charge" the chances of this (or anything like it) being
> accepted into Python are zero. I get a headache when I try to understand
> code that uses function composition, and I end up having to laboriously
> rewrite it using more traditional call notation before I move on to
> understanding what it actually does. Python is not Haskell, and perhaps
> more importantly, Python users are not like Haskel users. Either way, what
> may work out beautifully in Haskell will be like a fish out of water in
> Python.
> 
> I understand that it's fun to try to sole this puzzle, but evolving Python
> is more than solving puzzles. Enjoy debating the puzzle, but in the end
> Python will survive without the solution.


That old python-ideas thread could be of interest to you.

Best

Thomas


___
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] Why not picoseconds?

2017-10-16 Thread Thomas Jollans
On 2017-10-16 16:42, MRAB wrote:
> On 2017-10-16 13:30, Greg Ewing wrote:
>> Stephan Houben wrote:
>>
>>> Interestingly, that 2.2e-16 pretty much aligns with the accuracy of the
>>> cesium atomic clocks which are currently used to *define* the second.
>>> So we move to this new API, we should provide our own definition
>>> of the second, since those rough SI seconds are just too imprecise
>>> for that.
>>
>> The Python second: 1.1544865564196655e-06 of the time
>> taken for an unladen swallow to fly from Cape Town
>> to London.
>>
> Is that an African or a European swallow?

It starts African, but it flips and can be observed as either African or
European in London. It's a neutrino swallow.

-- 
Thomas Jollans
___
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] Restore the __members__ behavior to python3 for C extension writers

2017-06-19 Thread Thomas Jollans
On 2017-06-18 20:10, Barry Scott wrote:
> What is the way to tell python about 'value' in the python3 world? 

Implement a __dir__ method. This should call the superclass' (e.g.
object's) __dir__ and add whatever it is you want to add to the list.

In general I'd recommend using properties for this kind of thing rather
than messing with __getattr__, __setattr__ and __dir__, especially in
pure Python. I'm no expert on the C API, but I think this should be
possible by setting PyTypeObject.tp_getset
https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_getset


-- Thomas
___
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] Make functools.singledispatch register method return original function.

2017-06-17 Thread Thomas Jollans
On 17/06/17 23:27, Mital Ashok via Python-ideas wrote:
> [snip]
> So I'm suggesting that @function.register for single dispatch
> functions returns the same function, so you would end up with
> something like:
>
> @singledispatch
> def fun(arg, verbose=True):
> if verbose:
> print("Let me just say,", end=" ")
> print(arg)
>
> @fun.register(int)
> def fun(arg, verbose=True):
> if verbose:
> print("Strength in numbers, eh?", end=" ")
> print(arg)
In principle, I like it! However...
>
> And to get back the old behaviour, where you can get the function
> being decorated, just call it afterwards:

A backwards incompatible change like this is not going to happen.

In actual fact, a couple of uses of the current behaviour are in the
docs at
https://docs.python.org/3/library/functools.html#functools.singledispatch :

> The register() attribute returns the undecorated function which
> enables decorator stacking, pickling, as well as creating unit tests
> for each variant independently:
>
> >>>
> >>> @fun.register(float)
> ... @fun.register(Decimal)
> ... def fun_num(arg, verbose=False):
> ... if verbose:
> ... print("Half of your number:", end=" ")
> ... print(arg / 2)
> ...
> >>> fun_num is fun
> False

Perhaps it makes sense to add a new method to singledispatch that has
the behaviour you're suggesting, just with a different name?

-- Thomas

___
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] Define __fspath__() for NamedTemporaryFile and TemporaryDirectory

2017-06-16 Thread Thomas Jollans
On 08/06/17 15:42, Antoine Pietri wrote:
> Hello everyone!
>
> A very common pattern when dealing with temporary files is code like this:
>
> with tempfile.TemporaryDirectory() as tmpdir:
> tmp_path = tmpdir.name
>
> os.chmod(tmp_path)
> os.foobar(tmp_path)
> open(tmp_path).read(barquux)

Is it?

py> import tempfile
py> with tempfile.TemporaryDirectory() as tmpdir:
... print(tmpdir, type(tmpdir))
...
/tmp/tmp2kiqzmi9 
py>


>
> PEP 519 (https://www.python.org/dev/peps/pep-0519/) introduced the
> concept of "path-like objects", objects that define a __fspath__()
> method. Most of the standard library has been adapted so that the
> functions accept path-like objects.
>
> My proposal is to define __fspath__() for TemporaryDirectory and
> NamedTemporaryFile so that we can pass those directly to the library
> functions instead of having to use the .name attribute explicitely.
>
> Thoughts? :-)
>

-- 
Thomas Jollans

m ☎ +31 6 42630259
e ✉ t...@tjol.eu

___
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] π = math.pi

2017-06-07 Thread Thomas Jollans
On 2017-06-07 02:03, Mikhail V wrote:
> Greg Ewing wrote:
> 
>> Steven D'Aprano wrote:
>>> There's not much, if any, benefit to writing:
>>>
>>> ∫(expression, lower_limit, upper_limit, name)
> 
>> More generally, there's a kind of culture clash between mathematical
>> notation and programming notation. Mathematical notation tends to
>> almost exclusively use single-character names, relying on different
>> fonts and alphabets, and superscripts and subscripts, to get a large
>> enough set of identifiers. Whereas in programming we use a much
>> smaller alphabet and longer names.
> 
> That's probably because mathematicians grown up writing
> everything with a chalk on a blackboard.
> Hands are tired after hours of writing and blackboards
> are limitited, need to erase everything and start over.
> 

Also don't forget that mathematical formalism is *always* accompanied by
an explanation of what the symbols mean in the particular situation
(either orally by the person doing the writing, or in prose if it's in a
paper or book). Valid code, no matter how badly chosen the identifier
names, is always self-explanatory (at least to the computer); a
mathematical formula almost never is.

> I find actually symbols ≤ ≥ (inclusive comparison)
> nice. They look ok and have usage in context of writing
> code.
> But that's merely an exception in world of math symbols.
> OTOH I'm strongly against unicode.
> 
> 
> 
> Mikhail
> ___
> 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] π = math.pi

2017-06-03 Thread Thomas Jollans
On 03/06/17 21:02, Thomas Jollans wrote:
> On 03/06/17 20:41, Chris Angelico wrote:
>> [snip]
>> For reference, as well as the 948 Sm, there are 1690 Mn and 5777 So,
>> but only these characters are valid from them:
>>
>> \u1885 Mn MONGOLIAN LETTER ALI GALI BALUDA
>> \u1886 Mn MONGOLIAN LETTER ALI GALI THREE BALUDA
>> ℘ Sm SCRIPT CAPITAL P
>> ℮ So ESTIMATED SYMBOL
>>
>> 2118 SCRIPT CAPITAL P and 212E ESTIMATED SYMBOL are listed in
>> PropList.txt as Other_ID_Start, so they make sense. But that doesn't
>> explain the two characters from category Mn. It also doesn't explain
>> why U+309B and U+309C are *not* valid, despite being declared
>> Other_ID_Start. Maybe it's a bug? Maybe 309B and 309C somehow got
>> switched into 1885 and 1886??
> \u1885 and \u1886 are categorised as letters (category Lo) by my Python
> 3.5. (Which makes sense, right?) If your system puts them in category
> Mn, that's bound to be a bug somewhere.

Actually it turns out that these characters were changed to category Mn
in Unicode 9.0, but remain in (X)ID_Start for compatibility. All is
right with the world. (All of this just goes to show how much subtlety
there is in the science that goes into making Unicode)

See: http://www.unicode.org/reports/tr44/tr44-18.html#Unicode_9.0.0


>
> As for \u309B and \u309C - it turns out this is a question of
> normalisation. PEP 3131 requires NFKC normalisation:
>
>>>> for c in unicodedata.normalize('NFKC', '\u309B'):
> ... print('%s\tU+%04X\t%s' % (c, ord(c), unicodedata.name(c)))
> ...
>  U+0020SPACE
> U+3099COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK
>>>> for c in unicodedata.normalize('NFKC', '\u309C'):
> ... print('%s\tU+%04X\t%s' % (c, ord(c), unicodedata.name(c)))
> ...
>  U+0020SPACE
> U+309ACOMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
> This is interesting.
>
>
> Thomas
>
>
> _______
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/


-- 
Thomas Jollans

m ☎ +31 6 42630259
e ✉ t...@tjol.eu

___
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] π = math.pi

2017-06-03 Thread Thomas Jollans
On 03/06/17 20:41, Chris Angelico wrote:
> [snip]
> For reference, as well as the 948 Sm, there are 1690 Mn and 5777 So,
> but only these characters are valid from them:
>
> \u1885 Mn MONGOLIAN LETTER ALI GALI BALUDA
> \u1886 Mn MONGOLIAN LETTER ALI GALI THREE BALUDA
> ℘ Sm SCRIPT CAPITAL P
> ℮ So ESTIMATED SYMBOL
>
> 2118 SCRIPT CAPITAL P and 212E ESTIMATED SYMBOL are listed in
> PropList.txt as Other_ID_Start, so they make sense. But that doesn't
> explain the two characters from category Mn. It also doesn't explain
> why U+309B and U+309C are *not* valid, despite being declared
> Other_ID_Start. Maybe it's a bug? Maybe 309B and 309C somehow got
> switched into 1885 and 1886??

\u1885 and \u1886 are categorised as letters (category Lo) by my Python
3.5. (Which makes sense, right?) If your system puts them in category
Mn, that's bound to be a bug somewhere.

As for \u309B and \u309C - it turns out this is a question of
normalisation. PEP 3131 requires NFKC normalisation:

>>> for c in unicodedata.normalize('NFKC', '\u309B'):
... print('%s\tU+%04X\t%s' % (c, ord(c), unicodedata.name(c)))
...
 U+0020SPACE
U+3099COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK
>>> for c in unicodedata.normalize('NFKC', '\u309C'):
... print('%s\tU+%04X\t%s' % (c, ord(c), unicodedata.name(c)))
...
 U+0020SPACE
U+309ACOMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
>>>

This is interesting.


Thomas


___
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] π = math.pi

2017-06-03 Thread Thomas Jollans
On 03/06/17 18:48, Steven D'Aprano wrote:
> On Sun, Jun 04, 2017 at 02:36:50AM +1000, Steven D'Aprano wrote:
>
>> But Python 3.5 does treat it as an identifier!
>>
>> py> ℘ = 1  # should be a SyntaxError ?
>> py> ℘
>> 1
>>
>> There's a bug here, somewhere, I'm just not sure where...
> That appears to be the only Symbol Math character which is accepted as 
> an identifier in Python 3.5:
>
> py> import unicodedata
> py> all_unicode = map(chr, range(0x11))
> py> symbols = [c for c in all_unicode if unicodedata.category(c) == 'Sm']
> py> len(symbols)
> 948
> py> ns = {}
> py> for c in symbols:
> ... try:
> ... exec(c + " = 1", ns)
> ... except SyntaxError:
> ... pass
> ... else:
> ... print(c, unicodedata.name(c))
> ...
> ℘ SCRIPT CAPITAL P
> py>

This is actually not a bug in Python, but a quirk in Unicode.

I've had a closer look at PEP 3131 [1], which specifies that Python
identifiers follow the Unicode classes XID_Start and XID_Continue. ℘ is
listed in the standard [2][3] as XID_Start, so Python correctly accepts
it as an identifier.

>>> import unicodedata
>>> all_unicode = map(chr, range(0x11))
>>> for c in all_unicode:
... category = unicodedata.category(c)
... if not category.startswith('L') and category != 'Nl': # neither
letter nor letter-number
... if c.isidentifier():
... print('%s\tU+%04X\t%s' % (c, ord(c), unicodedata.name(c)))
...
_U+005FLOW LINE
℘U+2118SCRIPT CAPITAL P
℮U+212EESTIMATED SYMBOL
>>>

℘ and ℮ are actually explicitly mentioned in the Unicode annnex [3]:

>
>   2.5Backward Compatibility
>
> Unicode General_Category values are kept as stable as possible, but
> they can change across versions of the Unicode Standard. The bulk of
> the characters having a given value are determined by other
> properties, and the coverage expands in the future according to the
> assignment of those properties. In addition, the Other_ID_Start
> property provides a small list of characters that qualified as
> ID_Start characters in some previous version of Unicode solely on the
> basis of their General_Category properties, but that no longer qualify
> in the current version. These are called /grandfathered/ characters.
>
> The Other_ID_Start property includes characters such as the following:
>
> U+2118 ( ℘ ) SCRIPT CAPITAL P
> U+212E ( ℮ ) ESTIMATED SYMBOL
> U+309B ( ゛ ) KATAKANA-HIRAGANA VOICED SOUND MARK
> U+309C ( ゜ ) KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
>
>
I have no idea why U+309B and U+309C are not accepted as identifiers by
Python 3.5. This could be a question of Python following an old version
of the Unicode standard, or it *could* be a bug.


Thomas



[1]
https://www.python.org/dev/peps/pep-3131/#specification-of-language-changes
[2] http://www.unicode.org/Public/4.1.0/ucd/DerivedCoreProperties.txt
[3] http://www.unicode.org/reports/tr31/


___
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] π = math.pi

2017-06-03 Thread Thomas Jollans
On 01/06/17 20:11, Nikolaus Rath wrote:
> On Jun 01 2017, Victor Stinner 
> <victor.stinner-re5jqeeqqe8avxtiumw...@public.gmane.org> wrote:
>> 2017-06-01 8:47 GMT+02:00 Serhiy Storchaka <storch...@gmail.com>:
>>> What you are think about adding Unicode aliases for some mathematic names in
>>> the math module? ;-)
>>>
>>> math.π = math.pi
>> How do you write π (pi) with a keyboard on Windows, Linux or macOS?
> Under Linux, you'd use the Compose facility. Take a look at eg.
> /usr/share/X11/locale/en_US.UTF-8/Compose for all the nice things it
> let's you enter:
>
> $ egrep '[πτΓ]' /usr/share/X11/locale/en_US.UTF-8/Compose
>  : "Γ"   U0393# GREEK CAPITAL LETTER GAMMA
>  : "π"   U03C0# GREEK SMALL LETTER PI
>  : "τ"   U03C4# GREEK SMALL LETTER TAU
>

Have you ever seen a keyboard with a  key in real life, though?



-- 
Thomas Jollans

m ☎ +31 6 42630259
e ✉ t...@tjol.eu

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