Hi,
For technical reasons, many functions of the Python standard libraries
implemented in C have positional-only parameters. Example:
-------
$ ./python
Python 3.7.0a0 (default, Feb 25 2017, 04:30:32)
>>> help(str.replace)
replace(self, old, new, count=-1, /) # <== notice "/" at the end
...
>>> "a".replace("x", "y") # ok
'a'
>>> "a".replace(old="x", new="y") # ERR!
TypeError: replace() takes at least 2 arguments (0 given)
-------
When converting the methods of the builtin str type to the internal
"Argument Clinic" tool (tool to generate the function signature,
function docstring and the code to parse arguments in C), I asked if
we should add support for keyword arguments in str.replace(). The
answer was quick: no! It's a deliberate design choice.
Quote of Yury Selivanov's message:
"""
I think Guido explicitly stated that he doesn't like the idea to
always allow keyword arguments for all methods. I.e. `str.find('aaa')`
just reads better than `str.find(needle='aaa')`. Essentially, the idea
is that for most of the builtins that accept one or two arguments,
positional-only parameters are better.
"""
http://bugs.python.org/issue29286#msg285578
I just noticed a module on PyPI to implement this behaviour on Python functions:
https://pypi.python.org/pypi/positional
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?
Do you see concrete cases where it's a deliberate choice to deny
passing arguments as keywords?
Don't you like writing int(x="123") instead of int("123")? :-) (I know
that Serhiy Storshake hates the name of the "x" parameter of the int
constructor ;-))
By the way, I read that "/" marker is unknown by almost all Python
developers, and [...] syntax should be preferred, but
inspect.signature() doesn't support this syntax. Maybe we should fix
signature() and use [...] format instead?
Replace "replace(self, old, new, count=-1, /)" with "replace(self,
old, new[, count=-1])" (or maybe even not document the default
value?).
Python 3.5 help (docstring) uses "S.replace(old, new[, count])".
Victor
This way, I could do:
>>> authors = ["John", "Mary", "Estela"]
>>> "Authors: {:, j}".format(authors)
'Authors: John, Mary, Estela'
In this case the join can be made in the format yes, but this proposal
would be very useful when the info to format comes inside a structure
together with other stuff, like...
>>> info = {
... 'title': "A book",
... 'price': Decimal("2.34"),
... 'authors: ["John", "Mary", "Estela"],
... }
...
>>> print("{title!r} (${price}) by {authors:, j}".format(**info))
"A book" ($2.34) by John, Mary, Estela
What do you think?
--
. Facundo
Blog: http://www.taniquetil.com.ar/plog/
PyAr: http://www.python.org/ar/
Twitter: @facundobatista
Hi,
I'd like to bring back this discussion (from 2005, by Greg):
https://bugs.python.org/issue1229239
Briefly, non-heap types cannot have their
attributes changed by Python code. This makes sense for python builtin
types, but not for the types defined in extension/modules.
As we have been using this patch for the very same reasons and for more
than 10 years, I think it might make sense to reconsider the discussion
that Greg started.
The main question at that time was "why not using a heap type instead
?" (because heap-type do not have this limitation).
But I think that the right question could have been "why imposing such
a restriction on non-heap types as defined in (non Python core)
extensions ?".
I mean, to my knowledge, there is no reason why a type should be
allocated on the heap (https://docs.python.org/2/c-api/typeobj.html) to
be able to change its attributes at Python level.
I'm not saying that all non-heap types should be able to do so, just
that it would make sense to allow this behavior, as an option (bit
flag).
At the implementation level, the changes needed are really limited
(about a few lines):
- Include/object.h
- Objects/typeobject.c:
Eloi
Hi all,
We all know the bitwise operators: & (and), | (or), ^ (xor), and ~ (not).
We know how they work with numbers:
420 ^ 502
110100100
111110110
== XOR ==
001010010
= 82
But it might be useful in some cases to (let's say) xor a string (or
bytestring):
HELLO ^ world
01001000 01000101 01001100 01001100 01001111
01110111 01101111 01110010 01101100 01100100
=================== XOR ====================
00111111 00101010 00111110 00100000 00101011
= ?*> +
Currently, that's done with this expression for strings:
>>> ''.join(chr(ord(a) ^ ord(b)) for a, b in zip('HELLO', 'world'))
'?*> +'
and this expression for bytestrings:
>>> bytes(a ^ b for a, b in zip(b'HELLO', b'world'))
b'?*> +'
It would be much more convenient, however, to allow a simple xor of a
string:
>>> 'HELLO' ^ 'world'
'?*> +'
or bytestring:
>>> b'HELLO' ^ b'world'
b'?*> +'
(All of this applies to other bitwise operators, of course.)
Compatibility issues are a no-brainer - currently, bitwise operators for
strings raise TypeErrors.
Thanks.
Suggesting,
Ken
Hilton
;
Hi Ideas,
I often need to reference a script's current directory. I end up writing:
import os
SRC_DIR = os.path.dirname(__file__)
But I would prefer to have a new dunder for that. I propose: "__dir__". I
was wondering if others would find it convenient to include such a shortcut.
Here are some examples of dirname(__file__) in prominent projects.
https://github.com/tensorflow/models/search?l=Python&q=dirname&type=https://github.com/django/django/search?l=Python&q=dirname&type=https://github.com/nose-devs/nose/search?l=Python&q=dirname&type=
Reasons not to add __dir__:
* There already is one way to do it and it's clear and fairly short.
* Avoid the bikeshed discussion of __dir__, __folder__, and other
candidates.
Reasons to add it:
* os.path.dirname(__file__) returns the empty string when you're in the
same directory as the script. Luckily, os.path.join understands an empty
string as a ".", but this still is suboptimal for logging where it might be
surprising to find the empty string. __dir__ could be implemented to
contain a "." in that case.
* I would save about 20 characters and a line from 50% of my python scripts.
* This is such a common construct that everyone giving it their own name
seems suboptimal for communicating. Common names include: here, path,
dirname, module_dir.
Cheers,
Yuval Greenfield
P.s. nodejs has it -
https://nodejs.org/docs/latest/api/modules.html#modules_dirname also I
apologize if this has been suggested before - my googling didn't find a
previous thread.
I thought I would share a recent use I had for "given":
I have this comprehension:
potential_updates = {y: command.create_potential_update(y)
for x in need_initialization_nodes
for y in [x, *x.synthetic_inputs()]}
I want to filter out values that are None. I don't want to call the
function call twice, so I have to resort to using a loop and appending or
the for z in [y] trick. With "given", I can write:
potential_updates = {
y: potential_update
for x in need_initialization_nodes
for y in [x, *x.synthetic_inputs()]
given potential_update = command.create_potential_update(y)
if potential_update is not None}
I also wanted to point out that code like this is self-commenting because
the key and value of the comprehension can be given names.
On Tue May 22 22:08:40 (-0400), Chris Barker wrote:
> while asyncio is in the standard library, it is not intended to be THE
async event loop implementation
I'm surprised this is true - with dedicated syntax like async def/await,
it's still not THE async event loop implementation? As far as I know,
"async def" is a shorthand for
@asyncio.coroutine
def
and "await" is short for "yield from".
Sincerely,
Ken Hilton;
By 'self-contained', I meant that using the assert keyword and its expression is sufficient. An inline assertive expression as the one you describe does not fulfill this assert requirement.
My proposal is simply to extend the current assert to non-debug builds and allow to switch it off/on at runtime.
The syntax example I gave illustrated what I meant by syntax aware.
De : Serhiy Storchaka
Envoyé : samedi 5 mai à 15:10
Objet : Re: [Python-ideas] Runtime assertion with no overhead when not active
À : python-ideas(a)python.org
05.05.18 15:54, Eloi Gaudry пише: > I meant avoiding the overhead of the expression evaluation enclosed in the assert itself, not the active/disabled state (that comes at virtually no cost). > ex: >>>> runtime_assert( { i:None for i in range( 10000000 ) } ) > > By using the syntax you describe ('boolean and not expr'), you loose all the benefit of the Python grammar: > - self-contained Could you please explain what you mean? > - able to catch semantic/syntax bugs > > ex: >>>> f=1 >>>> runtime_assert( f==1 ) >>>> runtime_assert( f=1 ) > File "", line 1 > runtime_assert( f=1 ) > ^ > SyntaxError: invalid syntax Until inline assignment expression is implemented, this is an error too: >>> if debug and not f=1: File "", line 1 if debug and not f=1: ^ SyntaxError: invalid syntax _______________________________________________ Python-ideas mailing list Python-ideas(a)python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Hi folks,
I intend to add a runtime assertion feature in python. Before submitting a PEP, I am sending a draft to this mailing list to discuss whether it would make sense (above this message). I have actually been using it for the last 2 years and it has proven to be robust and has achieved its primary goal.
Briefly, the idea is to add a new assert that can be switch on/off depending on some variable/mechanism at runtime. The whole point of this assert is that it should not bring any overhead when off, i.e. by avoiding evaluating the expression enclosed in the runtime assert. It thus relies on Python grammar.
Thanks for your feedback.
Eloi
Abstract
This PEP aims at offering a runtime assert functionnality, extending the compiletime assert already available.
Rationale
There is no runtime assert relying on python grammar available. For diagnostics and/or debugging reasons, it would be valuable to add such a feature.
A runtime assert makes sense when extra checks would be needed in a production environment (where non-debug builds are used).
By extending the current python grammar, it would be possible to limit the overhead induces by those runtime asserts when running in a non "assertive" mode (-ed). The idea here is to avoid evaluating the expression when runtime assertion is not active.
A brief example why avoiding evaluating the expression is needed to avoid any overhead in case the runtime assert should be ignored.
::
runtime_assert( 999 in { i:None for i in range( 10000000 ) } )
Usage
::
runtime_assert( expr )
#would result in if expr and runtime_assert_active:
print RuntimeAssertionError()
Implementation details
There is already an implementation available, robust enough for production. The implementation is mainly grammar based, and thus the parser and the grammar needs to be updated:
* Python/graminit.c
* Python/ast.c
* Python/symtable.c
* Python/compile.c
* Python/Python-ast.c
* Python/sysmodule.c
* Modules/parsermodule.c
* Include/Python-ast.h
* Include/graminit.h
* Include/pydebug.h
* Grammar/Grammar
* Parser/Python.asdl
* Lib/lib2to3/Grammar.txt
* Lib/compiler/ast.py
* Lib/compiler/pycodegen.py
* Lib/compiler/transformer.py
* Lib/symbol.py
* Modules/parsermodule.c
References
[1]
PEP 306, How to Change Python's Grammar (http://www.python.org/dev/peps/pep-0306)
Copyright
This document has been placed in the public domain.
Hi!
I was working on handling some exceptions from external software
(e.g. database constraint triggers)
switching the handler based on the messages that had been sent.
Today we can do something like (running on Python 3.6.5):
>>> try:
... # [...]
... session.commit() # Here it raises!
... # [...]
... except DatabaseError as exc:
... msg = get_db_error_msg_from_exception(exc)
... if msg == "beyond_limit":
... # [...]
... elif msg == "no_funds":
... # [...]
... else:
... raise
That works, but I'd like to do something like:
>>> try:
... # [...]
... except BeyondLimit:
... # [...]
... except NoFunds:
... # [...]
Creating classes to "match" the exception in their __instancecheck__.
Well, I tried to do so. A simplified example would be:
>>> class MsgCheckerMeta(type):
... def __instancecheck__(cls, instance):
... return str(instance) == cls.internal
...
>>> class ExceptionHasMessage(Exception, metaclass=MsgCheckerMeta):
... internal = "message"
Using these new classes, we would get this:
>>> try:
... raise Exception("message")
... except ExceptionHasMessage:
... print("Yeah!")
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
Exception: message
Yet,
>>> isinstance(Exception("message"), ExceptionHasMessage)
True
>>> try:
... raise Exception("message")
... except Exception as exc:
... print(isinstance(exc, ExceptionHasMessage))
...
True
The idea is to allow catching exceptions beyond checking their MRO,
using a class that checks the exception instance by implementing
a custom __instancecheck__.
--
Danilo J. S. Bellini
---------------
"*It is not our business to set up prohibitions, but to arrive at
conventions.*" (R. Carnap)