[issue42557] Make asyncio.__main__ reusable, also adding a preamble feature.

2021-01-02 Thread Berry Schoenmakers


Change by Berry Schoenmakers :


--
keywords: +patch
pull_requests: +22889
stage:  -> patch review
pull_request: https://github.com/python/cpython/pull/24055

___
Python tracker 
<https://bugs.python.org/issue42557>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue42557] Make asyncio.__main__ reusable, also adding a preamble feature.

2020-12-03 Thread Berry Schoenmakers


New submission from Berry Schoenmakers :

The async REPL introduced in Python 3.8 is very nice for quick tests and 
experiments, supporting top-level "await" (see 
https://bugs.python.org/issue37028). I'm using it often when developing code 
that heavily relies on Python's asyncio module.

A drawback of the basic interface when launching it with "python -m asyncio" is 
that one usually still needs to enter a couple of statements to load the 
package you're working on, etc. To overcome this I've added a __main__.py to 
the mpyc package such that entering "python -m mpyc" will launch the async REPL 
like this: 

asyncio REPL 3.10.0a2 (tags/v3.10.0a2:114ee5d, Nov  3 2020, 00:37:42) 
[MSC v.1927 64 bit (AMD64)] on win32
Use "await" directly instead of "asyncio.run()".
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> from mpyc.runtime import mpc
>>> secint = mpc.SecInt()
>>> secfxp = mpc.SecFxp()
>>> secfld256 = mpc.SecFld(256)
>>>

This enables the async REPL but also a "preamble" with some additional code is 
executed.

To program mpyc.__main__.py, however, I basically had to copy 
asyncio.__main__.py and make a few changes throughout the code. It works 
alright, but to take advantage of future improvements to asyncio.__main__.py it 
would be very convenient if asyncio.__main__.py becomes reusable. 

With the added feature for specifying a "preamble", programming something like 
mpyc.__main__.py requires just a few lines of code:

import asyncio.__main__

if __name__ == '__main__':
preamble = ('from mpyc.runtime import mpc',
'secint = mpc.SecInt()',
'secfxp = mpc.SecFxp()',
'secfld256 = mpc.SecFld(256)')
 asyncio.__main__.main(preamble)

The attachment contains the current version of mpyc.__main__.py, which to a 
large extent duplicates code from asyncio.__main__.py. A couple of, I think, 
minor changes are applied to make the code reusable, and to add the preamble 
feature.

Would be nice if asyncio.__main__.py is updated in this manner in Python 3.10 
such that package developers can tailor it to their needs?

--
components: asyncio
files: __main__.py
messages: 382419
nosy: asvetlov, lschoe, vstinner, yselivanov
priority: normal
severity: normal
status: open
title: Make asyncio.__main__ reusable, also adding a preamble feature.
type: enhancement
versions: Python 3.10
Added file: https://bugs.python.org/file49652/__main__.py

___
Python tracker 
<https://bugs.python.org/issue42557>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue38237] Expose meaningful keyword arguments for pow()

2020-03-17 Thread Berry Schoenmakers


Berry Schoenmakers  added the comment:

Maybe a use case in this direction: int(x, base=10).
Because, if you type 

int(x='3', base=12)

you get

TypeError: 'x' is an invalid keyword argument for int()

and x needs to be a positional-only to program this yourself.

--

___
Python tracker 
<https://bugs.python.org/issue38237>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue38237] Expose meaningful keyword arguments for pow()

2020-03-17 Thread Berry Schoenmakers

Berry Schoenmakers  added the comment:

There seems to be a slight mixup with the built-in pow() function in Python 
3.8.2.

Currently, under https://docs.python.org/3/library/functions.html#pow it says:

Changed in version 3.9: Allow keyword arguments. Formerly, only 
positional arguments were supported.

I think this should be into "Changed in version 3.8 ... ", as pow(3,4, mod=5) 
actually works in Python 3.8.2.

The "What’s New In Python 3.8" also needs to be changed accordingly. 
In https://docs.python.org/3/whatsnew/3.8.html#positional-only-parameters it 
says:

One use case for this notation is that it allows pure Python functions 
to fully emulate behaviors of existing C coded functions. For example, the 
built-in pow() function does not accept keyword arguments:
def pow(x, y, z=None, /):
"Emulate the built in pow() function"
r = x ** y
return r if z is None else r%z

This example can simply be dropped now.

--
nosy: +lschoe

___
Python tracker 
<https://bugs.python.org/issue38237>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue38599] Deprecate creation of asyncio object when the loop is not running

2019-10-28 Thread Berry Schoenmakers


Berry Schoenmakers  added the comment:

Well, I'm basically using a run method defined as a shorthand for 
self.loop.run_until_complete (without closing loop, reusing it throughout). It 
would be nice if asyncio.run could simply be used instead, but I understand 
you're saying this is easier said than done, which is fine with me. Thanks.

--

___
Python tracker 
<https://bugs.python.org/issue38599>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue38599] Deprecate creation of asyncio object when the loop is not running

2019-10-28 Thread Berry Schoenmakers


Berry Schoenmakers  added the comment:

The current implementation of asyncio.run() is focused quite a bit on one-shot 
use. After the call returns, the default event loop is even gone: calling 
asyncio.get_event_loop() gives "RuntimeError: There is no current event loop in 
thread 'MainThread'."

It would be nice if asyncio.run() uses the default loop if it's available (and 
not running), and that the default loop remains intact after the call returns. 

This way multiple calls to asyncio.run() that all use the default loop are 
supported, maybe using an asyncio.Queue (or whatever) across these 
calls---attaching everything to the same (default) loop.

I find this very useful, for instance when writing unit tests.

--
nosy: +lschoe

___
Python tracker 
<https://bugs.python.org/issue38599>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36027] Support negative exponents in pow() where a modulus is specified.

2019-02-20 Thread Berry Schoenmakers


Berry Schoenmakers  added the comment:

In pure Python this seems to be the better option to compute inverses:

def modinv(a, m):  # assuming m > 0
b = m
s, s1 = 1, 0
while b:
a, (q, b) = b, divmod(a, b)
s, s1 = s1, s - q * s1
if a != 1:
raise ValueError('inverse does not exist')
return s if s >= 0 else s + m

Binary xgcd algorithms coded in pure Python run much slower.

--

___
Python tracker 
<https://bugs.python.org/issue36027>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36027] Consider adding modular multiplicative inverse to the math module

2019-02-19 Thread Berry Schoenmakers


Berry Schoenmakers  added the comment:

> Is there a clear reason for your expectation that the xgcd-based algorithm 
> should be faster?

Yeah, good question. Maybe I'm assuming too much, like assuming that it should 
be faster;) It may depend a lot on the constants indeed, but ultimately the 
xgcd style should prevail.

So the pow-based algorithm needs to do log(p) full-size muls, plus log(p) 
modular reductions. Karatsuba helps a bit to speed up the muls, but as far as I 
know it only kicks in for quite sizeable inputs. I forgot how Python is dealing 
with the modular reductions, but presumably that's done without divisions.

The xgcd-based algorithm needs to do a division per iteration, but the numbers 
are getting smaller over the course of the algorithm. And, the worst-case 
behavior occurs for things involving Fibonacci numbers only. In any case, the 
overall bit complexity is quadratic, even if division is quadratic. There may 
be a few expensive divisions along the way, but these also reduce the numbers a 
lot in size, which leads to good amortized complexity for each iteration.

--

___
Python tracker 
<https://bugs.python.org/issue36027>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36027] Consider adding modular multiplicative inverse to the math module

2019-02-19 Thread Berry Schoenmakers


Berry Schoenmakers  added the comment:

> ... to see `pow(a, p-2, p)` beat a pure Python xgcd for computing the inverse.

OK, I'm indeed assuming that modinv() is implemented efficiently, in CPython, 
like pow() is. Then, it should be considerably faster, maybe like this:

>>> timeit.timeit("gmpy2.invert(1023,p)", "import gmpy2; p=2**61-1")
0.18928535383349754
>>> timeit.timeit("gmpy2.invert(1023,p)", "import gmpy2; p=2**127-1")
0.290736872836419
>>> timeit.timeit("gmpy2.invert(1023,p)", "import gmpy2; p=2**521-1")
0.3317484429071
>>> timeit.timeit("gmpy2.powmod(1023,p-2,p)", "import gmpy2; p=2**61-1")
0.8771009990597349
>>> timeit.timeit("gmpy2.powmod(1023,p-2,p)", "import gmpy2; p=2**127-1")
3.460449585430979
>>> timeit.timeit("gmpy2.powmod(1023,p-2,p)", "import gmpy2; p=2**521-1")
84.3872797652

--

___
Python tracker 
<https://bugs.python.org/issue36027>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36027] Consider adding modular multiplicative inverse to the math module

2019-02-19 Thread Berry Schoenmakers


Berry Schoenmakers  added the comment:

Agreed, extending pow(value, n, modulus) to negative n would be a great 
addition!

To have modinv(value, modulus) next to that also makes a lot of sense to me, as 
this would avoid lots of confusion among users who are not so experienced with 
modular arithmetic. I know from working with generations of students and 
programmers how easy it is to make mistakes here (including lots of mistakes 
that I made myself;)

One would implement pow() for negative n, anyway, by first computing the 
modular inverse and then raising it to the power -n. So, to expose the modinv() 
function to the outside world won't cost much effort.

Modular powers, in particular, are often very confusing. Like for a prime 
modulus p, all of pow(a, -1,p), pow(a, p-2, p), pow(a, -p, p) are equal to 
eachother, but a common mistake is to take pow(a, p-1, p) instead. For a 
composite modulus things get much trickier still, as the exponent is then 
reduced in terms of the Euler phi function. 

And, even if you are not confused by these things, it's still a bit subtle that 
you have to use pow(a, -1,p) instead of pow(a, p-2, p) to let the modular 
inverse be computed efficiently. With modinv() available separately, one would 
expect --and get-- an efficient implementation with minimal overhead (e.g., not 
implemented via a complete extended-gcd).

--
nosy: +lschoe

___
Python tracker 
<https://bugs.python.org/issue36027>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue35996] Optional modulus argument for new math.prod() function

2019-02-15 Thread Berry Schoenmakers


Berry Schoenmakers  added the comment:

I had the same reservations but after rethinking it several times concluded 
that the modulus argument would fit really well.

Indeed, Mathematica doesn't support the Modulus option for the Product[] 
function. But they don't even support it for the Power[] function, one needs to 
use PowerMod[] for that. 

Python has the extra option for its built-in pow(), and sensibly restricts this 
to the case of integer arguments only. 

To do modular arithmetic, even with big numbers, in Python is really nice and 
easy using the % operator. And it's all pretty efficient as well. The only 
exception where efficiency becomes an issue is the pow() function.

To maintain that balance with the new prod() function around, the modulus 
argument would do the job. We can continue to do all modular arithmetic in a 
natural way, yielding programs that are perfectly readable and with very decent 
performance, now with prod() in the language as well.

Taking larger modular products is a common thing to do in modern crypto, and 
Python is a popular platform for this. Next to the example of prod_i g[i]**s[i] 
mod z, which is like a Pedersen multi-commitment, it also arises when computing 
Lagrange coefficients (used in Shamir secret sharing) and related determinants 
for Vandermonde matrices.

One would also be able to things like prod(range(1, n), n) == n - 1 for 
Wilson's primality test. (Extending the factorial() function with a modulus 
argument would be taking things too far, probably, but the modular version 
would now be available anyway via prod().)

So, my feeling is that there are sufficiently many use cases around. And, I'm 
kind of assuming that it's not too much effort to add a modulus argument to 
prod(), but maybe that's not really the case.

--

___
Python tracker 
<https://bugs.python.org/issue35996>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue35996] Optional modulus argument for new math.prod() function

2019-02-14 Thread Berry Schoenmakers


New submission from Berry Schoenmakers :

It's nice to see the arrival of the prod() function, see PR11359.

Just as for the built-in pow(x, y[, z]) function it would be very useful to 
have an optional argument z for computing integer products modulo z. Typical 
use case in cryptography would be:

prod((pow(x, y, z) for x, y in zip(g, s)), z)

to compute the product of all (potentially many) g[i]**s[i]'s modulo z. 

And, just as with the use of pow(), the intermediate values for prod() may in 
general grow quickly, hence modular reduction is essential to limit time and 
space usage.

Maybe an interesting option to add at this stage?

--
components: Library (Lib)
messages: 335557
nosy: lschoe, rhettinger
priority: normal
severity: normal
status: open
title: Optional modulus argument for new math.prod() function
type: performance
versions: Python 3.8

___
Python tracker 
<https://bugs.python.org/issue35996>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue35606] Add prod() function to the math module

2019-02-14 Thread Berry Schoenmakers


Berry Schoenmakers  added the comment:

Thanks for the suggestion, Mark.

I was not so sure, and the Nosy List for this issue is already quite extensive, 
so considered you guys as an appropriate audience for my first comment on this 
platform.

But I will also look into opening a separate issue later today.

--

___
Python tracker 
<https://bugs.python.org/issue35606>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue35606] Add prod() function to the math module

2019-02-14 Thread Berry Schoenmakers


Berry Schoenmakers  added the comment:

Nice to see the arrival of the prod() function.

Just as for the built-in pow(x, y[, z]) function it would be very useful to 
have an optional argument z for computing products modulo z. Typical use case 
in cryptography would be:

prod((pow(x, y, z) for x, y in zip(g, s)), z)

to compute the product of all (potentially many) g[i]**s[i]'s modulo z. 

And, just as with the use of pow(), the intermediate values for prod() may in 
general grow quickly, hence modular reduction is essential to limit time and 
space usage.

--
nosy: +lschoe

___
Python tracker 
<https://bugs.python.org/issue35606>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com