Re: [Python-ideas] What are the strong use cases for str.rindex()?

2019-04-25 Thread Steven D'Aprano
On Fri, Apr 26, 2019 at 12:17:57AM -0400, Terry Reedy wrote:
> On 4/25/2019 7:12 PM, Greg Ewing wrote:
> >Steven D'Aprano wrote:
> >>I too often forget that reverse() returns an iterator,
> 
> I presume you mean reversed().  list.reverse() is a list

Yes, I meant reversed(), not list.reverse() which is an in-place mutator 
method and returns None.

> >That seems like a mistake. Shouldn't it return a view?
> 
> RL = reversed(somelist) is already partly view-like.  The nth next call 
> returns the nth item at the time of the next call, rather than at the 
> time of the reversed call.  However, the number of items produced by 
> next calls is the length of the list at the time of the reversed call. 


That's not quite correct:

py> L = [1, 2, 3]
py> R = reversed(L)
py> L.clear()
py> next(R)
Traceback (most recent call last):
  File "", line 1, in 
StopIteration


It seems that:

- in-place modifications in the list are reflected in the items
  yielded (so reversed() doesn't make a copy of the list);

- operations which extend the length of the list don't show up 
  in the reversed version;

- and operations which decrease the length of the list decrease
  the number of items yielded.

That suggests to me an implementation similar to:

# untested
def reversed(alist):
N = len(alist)
for i in range(N-1, -1, -1):
try:
yield alist[i]
except IndexError:
break
raise StopIteration

which I suppose is close to what you meant here:

> The first next(RL) is the current somelist[captured_length].



-- 
Steven
___
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] What are the strong use cases for str.rindex()?

2019-04-25 Thread Steven D'Aprano
On Fri, Apr 26, 2019 at 11:12:51AM +1200, Greg Ewing wrote:
> Steven D'Aprano wrote:
> >I too often forget that reverse() returns an iterator,
> 
> That seems like a mistake. Shouldn't it return a view?

I don't know what it "should" or "shouldn't" it return, but it actually 
does return an iterator:

py> L = [1, 2, 3]
py> R = reversed(L)
py> hasattr(R, '__iter__') and iter(R) is R
True


-- 
Steven
___
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] What are the strong use cases for str.rindex()?

2019-04-25 Thread Terry Reedy

On 4/25/2019 7:12 PM, Greg Ewing wrote:

Steven D'Aprano wrote:

I too often forget that reverse() returns an iterator,


I presume you mean reversed().  list.reverse() is a list


That seems like a mistake. Shouldn't it return a view?


RL = reversed(somelist) is already partly view-like.  The nth next call 
returns the nth item at the time of the next call, rather than at the 
time of the reversed call.  However, the number of items produced by 
next calls is the length of the list at the time of the reversed call. 
The first next(RL) is the current somelist[captured_length].


>>> somelist = [1,2,3]
>>> RL = reversed(somelist)
>>> somelist[-1] = None
>>> somelist.append(4)
>>> list(RL)
[None, 2, 1]



--
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] Idea: Allow multiple levels of tracers

2019-04-25 Thread Anders Hovmöller


> On 26 Apr 2019, at 05:47, Ram Rachum  wrote:
> 
> Ah, I thought about it now and Ned is right. This would require modifications 
> to ceval.c and others.

Pity!

> The question is... Does anyone else think it's a good idea?


I do. It seems to me that coverage is a very useful tool that shouldn’t be 
unusable for certain programs if we can avoid it. If we should include it in 
CPython in the end probably depends on how much it complicates the 
implementation and/or how solid tests are written obviously.

I would point out that we can still get another coverage metric for these 
scenarios though: mutation coverage. But that’s extremely slow to collect 
compared to traditional coverage. 

/ Anders
___
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] Using rightarrow "->" for typing annotation of functions

2019-04-25 Thread Stephan Hoyer
On Thu, Apr 25, 2019 at 1:51 PM Ivan Levkivskyi 
wrote:

> TBH, I don't think it is so bad that it requires a new syntax. But I am
> not strongly against it either. What I would like to add here is that if we
> will go with the replacement:
>
> Callable[[X, Y], Z] becomes (X, Y) -> Z
>
> then we should also go with
>
> Union[X, Y] becomes X | Y
> Tuple[X, Y] becomes (X, Y)
>

This may not be workable, because A[X, Y] and A[(X, Y)] have identical
semantics in Python. So Tuple[(X, Y)] could either mean Tuple[X, Y] or
Tuple[Tuple[X, Y]].
___
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] Proposal: "?" Documentation Operator and easy reference to argument types/defaults/docstrings

2019-04-25 Thread Anders Hovmöller


> On 26 Apr 2019, at 00:41, Peter O'Connor  wrote:
> 
> - Defaults are defined in multiple places, which very easily leads to bugs 
> (I'm aware of **kwargs but it obfuscates function interfaces and usually does 
> more harm than good)
> - Types are defined in multiple places
> - Documentation is copy-pasted when referencing a single thing from different 
> places.  (I can't count the number of types I've written ":param img: A 
> (size_y, size_x, 3) RGB image" - I could now just reference a single 
> RGB_IMAGE_DOC variable)
> - Argument names need to be written twice - in the header and documentation - 
> and it's up to the user / IDE to make sure they stay in sync.


We have this exact problem in many places in tri.form, tri.query, tri.table and 
the code bases that use them. I would really like a solution to these! But you 
don’t seem to address these problems at all in the rest of your email, which 
makes me confused. In general I think what we want is an agreed upon way to 
specify argument names, counts and defaults for use by static analysis tools, 
documentation generation tools and IDEs, in a programmatic way. This could 
solve the problems you reference above, and also the issue of how to supply 
auto complete for something like Djangos query language (where you can do 
SomeTable.objects.filter(foreignkey__anotherforeignkey__value=3) which is 
great!).

Maybe something like...

def foo(**kwargs):
“””
@signature_by: full.module.path.to.a.signature_function(pass_kwargs_to=bar, 
hardcoded=[‘quux’])
“””
return bar(**kwargs, quux=3)


def signature_function(f, pass_kwargs_to=None, hardcoded=None, **_):
signature = inspect.signature(f)
if pass_kwargs_to is not None:
signature_nested = inspect.signature(pass_kwargs_to)
signature.remove_kwargs()
signature = signature.merge(signature_nested)
if hardcoded is not None:
for h in hardcoded:
signature.parameters.remove(h)
return signature


Some of the above is pseudo code obviously.

What do you think?

/ Anders___
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] Idea: Allow multiple levels of tracers

2019-04-25 Thread Ram Rachum
Ah, I thought about it now and Ned is right. This would require
modifications to ceval.c and others.

The question is... Does anyone else think it's a good idea?

On Fri, Apr 26, 2019 at 12:31 AM Ned Batchelder 
wrote:

> It wouldn't be difficult to have a list of trace functions, so that every
> line of "real" Python executed, would invoke all the trace functions.  But
> Ram has asked for something more: when the first trace function is
> executing, its line should themselves be traced by the remaining trace
> functions in the list.  Presumably the lines in the second trace function
> should also be traced by the function third in the list, and so on.  This
> is the thing that will be difficult to accomplish.
>
> --Ned.
> On 4/25/19 2:02 PM, Anders Hovmöller wrote:
>
> Well, it would trigger the top level chaining trace function, but they
> should be able to decide when to call the sub-trace functions. Hmm... Maybe
> :)
>
> On 25 Apr 2019, at 19:16, Ned Batchelder  wrote:
>
> Perhaps I misunderstand what's implied by "simple(!) monkeypatch of
> sys.settrace", but the trickiest part of Ram's proposal is that the body of
> one trace function would still trigger the remaining trace functions.  That
> to me sounds like it's going to require changes to ceval.c
>
> --Ned.
> On 4/25/19 12:26 PM, Ram Rachum wrote:
>
> Hmm, looks like, for this to work, you'll need the existing tracer to be
> cooperative. Right now there are existing tracers, for example coverage's
> tracer and Wing IDE's tracer, and I would need to modify them for your idea
> to work, right?
>
> If I understand your idea correctly, the first tracer would monkeypatch
> `sys.settrace` so whenever someone else adds a tracer, it doesn't really do
> `sys.settrace` but just add a function that the real tracer would be
> calling after it's done tracing. But this can't really be done without the
> original tracer implementing it, right?
>
> On Thu, Apr 25, 2019 at 6:16 PM Ram Rachum  wrote:
>
>> Oh wow, I didn't even consider that. I think you're right, I'll do more
>> thinking about this. Thanks Anders!
>>
>> On Thu, Apr 25, 2019 at 6:10 PM Anders Hovmöller 
>> wrote:
>>
>>> Can't this be implemented today by a simple monkey patch of sys.settrace?
>>>
>>> On 25 Apr 2019, at 16:51, Ram Rachum  wrote:
>>>
>>> Hi,
>>>
>>> Here's something I want in Python: Multiple levels of tracers working on
>>> top of each other, instead of just one.
>>>
>>> I'm talking about the tracer that one can set by calling sys.settrace.
>>>
>>> I've recently released PySnooper: https://github.com/cool-RR/PySnooper/
>>>
>>> One of the difficulties I have, is that I can't debug or run the
>>> `coverage` tool on the core of this module. That's because the core is a
>>> trace function, and debuggers and coverage tools work by setting a trace
>>> function. When PySnooper sets its trace function using `sys.settrace`, the
>>> code that runs in that trace function runs without getting traced by the
>>> coverage tracer.
>>>
>>> This means that people who develop debuggers and coverage tools can't
>>> use a debugger or a coverage tool on the core of their tool. It's quite an
>>> annoying problem.
>>>
>>> My proposed solution: Multiple levels of tracing, instead of just one.
>>> When you install a tracer, you're not replacing the existing one, you're
>>> appending a tracer to the existing list of tracers.
>>>
>>> If this was implemented, then when PySnooper would install its tracer,
>>> the coverage tracer would still be active and running, for every line of
>>> code including the ones in PySnooper's tracer.
>>>
>>> Obviously, we'll need to figure out the API and any other kind of
>>> problems with this proposal.
>>>
>>> What do you think?
>>>
>>>
>>> Thanks,
>>> Ram.
>>>
>>>
>>> ___
>>> 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 
> listPython-ideas@python.orghttps://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/
>
___
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] Using rightarrow "->" for typing annotation of functions

2019-04-25 Thread Tony Yu
Ivan Levkivskyi  wrote:

> Callable[[X, Y], Z] becomes (X, Y) -> Z
> Union[X, Y] becomes X | Y
> Tuple[X, Y] becomes (X, Y)
> Optional[X] becomes X?
> (Intersection[X, Y] when added becomes X & Y)
>

I really like this idea, but I could also see this getting a bit confusing
because the syntax preceding type annotations (e.g. ":") is so
lightweight/subtle---it might be difficult distinguish were annotations end
and subsequent code begins.

Defining some sort of wrapper function might help here; e.g.:

Callable[[X, Y], Z] becomes  EzType[(X, Y) => Z]
Union[X, Y] becomes EzType[X | Y]
Tuple[X, Y] becomes EzType[X, Y]
Optional[X] becomes EzType[X?]
...

The name EzType is certainly not ideal, but you get the basic idea.

---
Tony


On Thu, Apr 25, 2019 at 3:51 PM Ivan Levkivskyi 
wrote:

> TBH, I don't think it is so bad that it requires a new syntax. But I am
> not strongly against it either. What I would like to add here is that if we
> will go with the replacement:
>
> Callable[[X, Y], Z] becomes (X, Y) -> Z
>
> then we should also go with
>
> Union[X, Y] becomes X | Y
> Tuple[X, Y] becomes (X, Y)
> Optional[X] becomes X?
> (Intersection[X, Y] when added becomes X & Y)
>
> The current syntax (although really verbose) is consistent, so if we want
> to improve it I would like to keep consistency.
> Also if we are going forward with this, should we allow mixing old and new
> syntax? Will the old syntax be deprecated after we introduce the new one?
>
> --
> Ivan
>
>
>
> On Wed, 24 Apr 2019 at 14:43, Guido van Rossum  wrote:
>
>> Thanks for posting. I agree that Callable is ugly (even hideous :-), but
>> when we introduced type annotations in PEP 484, we didn't want to introduce
>> new syntax. The existing syntax (using -> in function headings) was
>> supported since Python 3.0.
>>
>> Since then we've introduced other new syntax (in particular PEP 526) so
>> we could indeed try adding something better for Callable.
>>
>> I think we should probably at least have parentheses around the
>> arguments, so you'd write
>>
>> f: (int) -> str
>> g: (int, str) -> float
>>
>> That looks elegant.
>>
>> But we should also try to support optional arguments and keyword
>> arguments.
>>
>> Also, some groups of people would like to see a more concise notation for
>> lambdas, and maybe they'd want to write
>>
>> x = (a, b) -> a + b
>>
>> as sugar for
>>
>> x = lambda a, b: a + b
>>
>> We probably can't have both, so we should at least decide which is more
>> important.
>>
>> Too bad we can't use Unicode arrows. :-)
>>
>> On Wed, Apr 24, 2019 at 2:30 PM Vaibhav Karve 
>> wrote:
>>
>>> (Note: This idea is about a particular static typecheking (typing?)
>>> annotation syntax).
>>> The idea is that currently the use of the "->" (right arrow) is
>>> restricted to only function definition annotation. Can we extent it to
>>> declaration of type for functions even outside their definitions?
>>> Example:
>>>
>>> Currently we write:
>>> f: Callable[[int, Dict[str, int]], str]  # declaring the type of
>>> some fake function
>>>
>>> This would be much cleaner if we could write:
>>> f: int -> Dict[str, int] -> str   # One of the possibilities
>>>
>>> or even:
>>> f: int, Dict[str, int] -> str  # Another possibility
>>>
>>> I have no idea how this will affect the existing syntax (and if this
>>> will have any bad repercussions/notational misuse). I just thought it would
>>> be nicer to:
>>> a) Not have to spell out Callable
>>> b) Not have to use all those square brackets
>>> c) Have the same notation work for both the function annotation as well
>>> as for declaring the type.
>>>
>>> This is my first time posting an idea to python-ideas. So apologies if i
>>> am not following some conventions that i might not be aware of.
>>> Vaibhav Karve
>>> ___
>>> Python-ideas mailing list
>>> Python-ideas@python.org
>>> https://mail.python.org/mailman/listinfo/python-ideas
>>> Code of Conduct: http://python.org/psf/codeofconduct/
>>>
>>
>>
>> --
>> --Guido van Rossum (python.org/~guido)
>> *Pronouns: he/him/his **(why is my pronoun here?)*
>> 
>> ___
>> 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] Proposal: "?" Documentation Operator and easy reference to argument types/defaults/docstrings

2019-04-25 Thread David Mertz
On Thu, Apr 25, 2019 at 6:42 PM Peter O'Connor 
wrote:

> Despite the general beauty of Python, I find myself constantly violating
> the "don't repeat yourself" maxim when trying to write clear, fully
> documented code.  Take the following example:
>

You do know that OPTIONAL type annotations are optional, right.  There's no
requirement to repeat yourself if you don't want to.

But in general, comments or docstrings can do something very different from
just annotate one variable at a time.  If I want to describe the
interaction of `a` and `b`, that simply cannot fit in an annotation/comment
per parameter.  Of if one argument switches the relevance or meaning of
another, etc.


> - Argument/return documentation can be made inline with a new "?"
> operator.  Documentation becomes a first class citizen.
>

We already have a first-class citizen in annotations, this seems like extra
burden for little reason.


> def func_1(
> a: int = 1 ? 'Something about param a',
> b: float = 2.5 ? 'Something else about param b',
> ) -> float ? 'Something about return value of func_1':
> """ Something about func_1 """
> return a*b
>

Why not just this in existing Python:

def func_1(
a: int = 1 # 'Something about param a',
b: float = 2.5 # 'Something else about param b',
) -> float:
"""Something about func_1

a and b interact in this interesting way.
a should be in range 0 < a < 125
floor(b) should be a prime number

Something about return value of func_1
returns a multiplication
"""
return a*b


-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
___
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] Using rightarrow "->" for typing annotation of functions

2019-04-25 Thread Greg Ewing

Guido van Rossum wrote:
Also, some groups of people would like to see a more concise notation 
for lambdas, and maybe they'd want to write


x = (a, b) -> a + b

We probably can't have both,


I think we could if we wanted to. In an annotation, -> could be treated
as sugar for Callable[], and in other expressions as sugar for lambda.

--
Greg


___
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] What are the strong use cases for str.rindex()?

2019-04-25 Thread Greg Ewing

Steven D'Aprano wrote:

I too often forget that reverse() returns an iterator,


That seems like a mistake. Shouldn't it return a view?

--
Greg

___
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] Open parenthesis in REPL completion

2019-04-25 Thread Greg Ewing

Steven D'Aprano wrote:
But having the opening bracket auto-added is a small satisfaction, and 
if you're using the REPL for actual calculations and not just help(), 
the benefit probably outweighs the annoyance


The completer could detect the help( as well and leave out
the opening paren in that case.

--
Greg
___
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] Proposal: "?" Documentation Operator and easy reference to argument types/defaults/docstrings

2019-04-25 Thread Robert Vanden Eynde
Looks like a more complicated way to say :

def f(x:'int : which does stuff' = 5, y:'int : which does more stuffs')

The code reading the annotations (like the linter) might then parse it
simply using .split.

robertvandeneynde.be

Le ven. 26 avr. 2019 à 00:41, Peter O'Connor  a
écrit :

> Dear all,
>
> Despite the general beauty of Python, I find myself constantly violating
> the "don't repeat yourself" maxim when trying to write clear, fully
> documented code.  Take the following example:
>
> def func_1(a: int = 1, b: float = 2.5) -> float:
> """
> Something about func_1
> :param a: Something about param a
> :param b: Something else about param b
> :return: Something about return value of func_1
> """
> return a*b
>
> def func_2(c:float=3.4, d: bool =True) -> float:
> """
> Something about func_2
> :param c: Something about param c
> :param d: Something else about param d
> :return: Something about return value
> """
> return c if d else -c
>
> def main_function(a: int = 1, b: float = 2.5, d: bool = True) -> float:
> """
> Something about main_function
> :param a: Something about param a
> :param b: Something else about param b
> :param d: Something else about param d
> :return: Something about return value
> """
> return func_2(func_1(a=a, b=b), d=d)
>
> Which has the following problems:
> - Defaults are defined in multiple places, which very easily leads to bugs
> (I'm aware of **kwargs but it obfuscates function interfaces and usually
> does more harm than good)
> - Types are defined in multiple places
> - Documentation is copy-pasted when referencing a single thing from
> different places.  (I can't count the number of types I've written ":param
> img: A (size_y, size_x, 3) RGB image" - I could now just reference a single
> RGB_IMAGE_DOC variable)
> - Argument names need to be written twice - in the header and
> documentation - and it's up to the user / IDE to make sure they stay in
> sync.
>
> I propose to resolve this with the following changes:
> - Argument/return documentation can be made inline with a new "?"
> operator.  Documentation becomes a first class citizen.
> - Argument (type/default/doc) can be referenced by "func.args..type"
> / "func.args..default" / "func.args..doc".
> Positional reference: e.g. "func.args[1].default" also allowed.  If not
> specified, they take a special, built-in "Undefined" value (because None
> may have another meaning for defaults).  Return type/doc can be referenced
> with "func.return.type" / "func.return.doc".
>
> This would result in the following syntax:
>
> def func_1(
> a: int = 1 ? 'Something about param a',
> b: float = 2.5 ? 'Something else about param b',
> ) -> float ? 'Something about return value of func_1':
> """ Something about func_1 """
> return a*b
>
> def func_2(
> c: float=3.4 ? 'Something about param c',
> d: bool =True ? 'Something else about param d',
> ) -> float ? 'Something about return value':
> """ Something about func_2 """
> return c if d else -c
>
> def main_function(
> a: func_1.args.a.type = func_1.args.a.default ?
> func_1.args.a.doc,
> b: func_1.args.b.type = func_1.args.b.default ?
> func_1.args.b.doc,
> d: func_2.args.d.type = func_2.args.d.default ?
> func_2.args.d.doc,
> ) -> func_2.return.type ? func2.return.doc:
> """ Something about main_function """
> return func_2(func_1(a=a, b=b), d=d)
>
> If the main_function header seems repetitious (it does) we could allow for
> an optional shorthand notation like:
>
> def main_function(
> a :=? func_1.args.a,
> b :=? func_1.args.b,
> d :=? func_2.args.d,
> ) ->? func_2.return:
> """ Something about main_function """
> return func_2(func_1(a=a, b=b), d=d)
>
> Where "a :=? func_1.args.a" means "argument 'a' takes the same
> type/default/documentation as argument 'a' of func_1".
>
> So what do you say?  Yes it's a bold move, but I think in the long term
> it's badly needed.  Perhaps something similar has been proposed already
> that I'm not aware of.
> ___
> 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] Proposal: "?" Documentation Operator and easy reference to argument types/defaults/docstrings

2019-04-25 Thread Chris Angelico
On Fri, Apr 26, 2019 at 8:42 AM Peter O'Connor
 wrote:
>
> Dear all,
>
> Despite the general beauty of Python, I find myself constantly violating the 
> "don't repeat yourself" maxim when trying to write clear, fully documented 
> code.  Take the following example:
>
> def func_1(a: int = 1, b: float = 2.5) -> float:
> """
> Something about func_1
> :param a: Something about param a
> :param b: Something else about param b
> :return: Something about return value of func_1
> """
> return a*b
>
> def func_2(c:float=3.4, d: bool =True) -> float:
> """
> Something about func_2
> :param c: Something about param c
> :param d: Something else about param d
> :return: Something about return value
> """
> return c if d else -c
>
> def main_function(a: int = 1, b: float = 2.5, d: bool = True) -> float:
> """
> Something about main_function
> :param a: Something about param a
> :param b: Something else about param b
> :param d: Something else about param d
> :return: Something about return value
> """
> return func_2(func_1(a=a, b=b), d=d)
>
> Which has the following problems:
> - Defaults are defined in multiple places, which very easily leads to bugs 
> (I'm aware of **kwargs but it obfuscates function interfaces and usually does 
> more harm than good)
>

I'd actually rather explore fixing this problem than the other. We
have functools.wraps() for the case where you do nothing other than
pass through *a,**kw, but when you want to add or remove an argument,
I don't think there's an easy way to say "that function's signature,
but with these changes". That way, you aren't obfuscating the
interface (since the called function's signature is incorporated into
the wrapper's), and you're not duplicating defaults or anything.

It shouldn't need to be all that complicated to use (although I'm sure
it'll be complicated to implement). Something like:

@functools.passes_args(f)
def wrapper(spam, ham, *a, **kw):
f(*a, **kw)

There would need to be parameters to indicate the addition of
parameters, but it could detect the removal (which is common for
wrappers) just from the function's own signature.

If that were implemented, would it remove the need for this new syntax
you propose?

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] Proposal: "?" Documentation Operator and easy reference to argument types/defaults/docstrings

2019-04-25 Thread Peter O'Connor
Dear all,

Despite the general beauty of Python, I find myself constantly violating
the "don't repeat yourself" maxim when trying to write clear, fully
documented code.  Take the following example:

def func_1(a: int = 1, b: float = 2.5) -> float:
"""
Something about func_1
:param a: Something about param a
:param b: Something else about param b
:return: Something about return value of func_1
"""
return a*b

def func_2(c:float=3.4, d: bool =True) -> float:
"""
Something about func_2
:param c: Something about param c
:param d: Something else about param d
:return: Something about return value
"""
return c if d else -c

def main_function(a: int = 1, b: float = 2.5, d: bool = True) -> float:
"""
Something about main_function
:param a: Something about param a
:param b: Something else about param b
:param d: Something else about param d
:return: Something about return value
"""
return func_2(func_1(a=a, b=b), d=d)

Which has the following problems:
- Defaults are defined in multiple places, which very easily leads to bugs
(I'm aware of **kwargs but it obfuscates function interfaces and usually
does more harm than good)
- Types are defined in multiple places
- Documentation is copy-pasted when referencing a single thing from
different places.  (I can't count the number of types I've written ":param
img: A (size_y, size_x, 3) RGB image" - I could now just reference a single
RGB_IMAGE_DOC variable)
- Argument names need to be written twice - in the header and documentation
- and it's up to the user / IDE to make sure they stay in sync.

I propose to resolve this with the following changes:
- Argument/return documentation can be made inline with a new "?"
operator.  Documentation becomes a first class citizen.
- Argument (type/default/doc) can be referenced by "func.args..type"
/ "func.args..default" / "func.args..doc".  Positional
reference: e.g. "func.args[1].default" also allowed.  If not specified,
they take a special, built-in "Undefined" value (because None may have
another meaning for defaults).  Return type/doc can be referenced with
"func.return.type"
/ "func.return.doc".

This would result in the following syntax:

def func_1(
a: int = 1 ? 'Something about param a',
b: float = 2.5 ? 'Something else about param b',
) -> float ? 'Something about return value of func_1':
""" Something about func_1 """
return a*b

def func_2(
c: float=3.4 ? 'Something about param c',
d: bool =True ? 'Something else about param d',
) -> float ? 'Something about return value':
""" Something about func_2 """
return c if d else -c

def main_function(
a: func_1.args.a.type = func_1.args.a.default ?
func_1.args.a.doc,
b: func_1.args.b.type = func_1.args.b.default ?
func_1.args.b.doc,
d: func_2.args.d.type = func_2.args.d.default ?
func_2.args.d.doc,
) -> func_2.return.type ? func2.return.doc:
""" Something about main_function """
return func_2(func_1(a=a, b=b), d=d)

If the main_function header seems repetitious (it does) we could allow for
an optional shorthand notation like:

def main_function(
a :=? func_1.args.a,
b :=? func_1.args.b,
d :=? func_2.args.d,
) ->? func_2.return:
""" Something about main_function """
return func_2(func_1(a=a, b=b), d=d)

Where "a :=? func_1.args.a" means "argument 'a' takes the same
type/default/documentation as argument 'a' of func_1".

So what do you say?  Yes it's a bold move, but I think in the long term
it's badly needed.  Perhaps something similar has been proposed already
that I'm not aware of.
___
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] Idea: Allow multiple levels of tracers

2019-04-25 Thread Ned Batchelder
It wouldn't be difficult to have a list of trace functions, so that 
every line of "real" Python executed, would invoke all the trace 
functions.  But Ram has asked for something more: when the first trace 
function is executing, its line should themselves be traced by the 
remaining trace functions in the list.  Presumably the lines in the 
second trace function should also be traced by the function third in the 
list, and so on.  This is the thing that will be difficult to accomplish.


--Ned.

On 4/25/19 2:02 PM, Anders Hovmöller wrote:
Well, it would trigger the top level chaining trace function, but they 
should be able to decide when to call the sub-trace functions. Hmm... 
Maybe :)


On 25 Apr 2019, at 19:16, Ned Batchelder > wrote:


Perhaps I misunderstand what's implied by "simple(!) monkeypatch of 
sys.settrace", but the trickiest part of Ram's proposal is that the 
body of one trace function would still trigger the remaining trace 
functions.  That to me sounds like it's going to require changes to 
ceval.c


--Ned.

On 4/25/19 12:26 PM, Ram Rachum wrote:
Hmm, looks like, for this to work, you'll need the existing tracer 
to be cooperative. Right now there are existing tracers, for example 
coverage's tracer and Wing IDE's tracer, and I would need to modify 
them for your idea to work, right?


If I understand your idea correctly, the first tracer would 
monkeypatch `sys.settrace` so whenever someone else adds a tracer, 
it doesn't really do `sys.settrace` but just add a function that the 
real tracer would be calling after it's done tracing. But this can't 
really be done without the original tracer implementing it, right?


On Thu, Apr 25, 2019 at 6:16 PM Ram Rachum > wrote:


Oh wow, I didn't even consider that. I think you're right, I'll
do more thinking about this. Thanks Anders!

On Thu, Apr 25, 2019 at 6:10 PM Anders Hovmöller
mailto:bo...@killingar.net>> wrote:

Can't this be implemented today by a simple monkey patch of
sys.settrace?

On 25 Apr 2019, at 16:51, Ram Rachum mailto:r...@rachum.com>> wrote:


Hi,

Here's something I want in Python: Multiple levels of
tracers working on top of each other, instead of just one.

I'm talking about the tracer that one can set by calling
sys.settrace.

I've recently released PySnooper:
https://github.com/cool-RR/PySnooper/

One of the difficulties I have, is that I can't debug or
run the `coverage` tool on the core of this module. That's
because the core is a trace function, and debuggers and
coverage tools work by setting a trace function. When
PySnooper sets its trace function using `sys.settrace`, the
code that runs in that trace function runs without getting
traced by the coverage tracer.

This means that people who develop debuggers and coverage
tools can't use a debugger or a coverage tool on the core
of their tool. It's quite an annoying problem.

My proposed solution: Multiple levels of tracing, instead
of just one. When you install a tracer, you're not
replacing the existing one, you're appending a tracer to
the existing list of tracers.

If this was implemented, then when PySnooper would install
its tracer, the coverage tracer would still be active and
running, for every line of code including the ones in
PySnooper's tracer.

Obviously, we'll need to figure out the API and any other
kind of problems with this proposal.

What do you think?


Thanks,
Ram.


___
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/
___
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] Using rightarrow "->" for typing annotation of functions

2019-04-25 Thread Ivan Levkivskyi
TBH, I don't think it is so bad that it requires a new syntax. But I am not
strongly against it either. What I would like to add here is that if we
will go with the replacement:

Callable[[X, Y], Z] becomes (X, Y) -> Z

then we should also go with

Union[X, Y] becomes X | Y
Tuple[X, Y] becomes (X, Y)
Optional[X] becomes X?
(Intersection[X, Y] when added becomes X & Y)

The current syntax (although really verbose) is consistent, so if we want
to improve it I would like to keep consistency.
Also if we are going forward with this, should we allow mixing old and new
syntax? Will the old syntax be deprecated after we introduce the new one?

--
Ivan



On Wed, 24 Apr 2019 at 14:43, Guido van Rossum  wrote:

> Thanks for posting. I agree that Callable is ugly (even hideous :-), but
> when we introduced type annotations in PEP 484, we didn't want to introduce
> new syntax. The existing syntax (using -> in function headings) was
> supported since Python 3.0.
>
> Since then we've introduced other new syntax (in particular PEP 526) so we
> could indeed try adding something better for Callable.
>
> I think we should probably at least have parentheses around the arguments,
> so you'd write
>
> f: (int) -> str
> g: (int, str) -> float
>
> That looks elegant.
>
> But we should also try to support optional arguments and keyword arguments.
>
> Also, some groups of people would like to see a more concise notation for
> lambdas, and maybe they'd want to write
>
> x = (a, b) -> a + b
>
> as sugar for
>
> x = lambda a, b: a + b
>
> We probably can't have both, so we should at least decide which is more
> important.
>
> Too bad we can't use Unicode arrows. :-)
>
> On Wed, Apr 24, 2019 at 2:30 PM Vaibhav Karve 
> wrote:
>
>> (Note: This idea is about a particular static typecheking (typing?)
>> annotation syntax).
>> The idea is that currently the use of the "->" (right arrow) is
>> restricted to only function definition annotation. Can we extent it to
>> declaration of type for functions even outside their definitions?
>> Example:
>>
>> Currently we write:
>> f: Callable[[int, Dict[str, int]], str]  # declaring the type of some
>> fake function
>>
>> This would be much cleaner if we could write:
>> f: int -> Dict[str, int] -> str   # One of the possibilities
>>
>> or even:
>> f: int, Dict[str, int] -> str  # Another possibility
>>
>> I have no idea how this will affect the existing syntax (and if this will
>> have any bad repercussions/notational misuse). I just thought it would be
>> nicer to:
>> a) Not have to spell out Callable
>> b) Not have to use all those square brackets
>> c) Have the same notation work for both the function annotation as well
>> as for declaring the type.
>>
>> This is my first time posting an idea to python-ideas. So apologies if i
>> am not following some conventions that i might not be aware of.
>> Vaibhav Karve
>> ___
>> Python-ideas mailing list
>> Python-ideas@python.org
>> https://mail.python.org/mailman/listinfo/python-ideas
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>
>
> --
> --Guido van Rossum (python.org/~guido)
> *Pronouns: he/him/his **(why is my pronoun here?)*
> 
> ___
> 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] Idea: Allow multiple levels of tracers

2019-04-25 Thread Anders Hovmöller
Well, it would trigger the top level chaining trace function, but they should 
be able to decide when to call the sub-trace functions. Hmm... Maybe :)

> On 25 Apr 2019, at 19:16, Ned Batchelder  wrote:
> 
> Perhaps I misunderstand what's implied by "simple(!) monkeypatch of 
> sys.settrace", but the trickiest part of Ram's proposal is that the body of 
> one trace function would still trigger the remaining trace functions.  That 
> to me sounds like it's going to require changes to ceval.c
> 
> --Ned.
> 
>> On 4/25/19 12:26 PM, Ram Rachum wrote:
>> Hmm, looks like, for this to work, you'll need the existing tracer to be 
>> cooperative. Right now there are existing tracers, for example coverage's 
>> tracer and Wing IDE's tracer, and I would need to modify them for your idea 
>> to work, right?
>> 
>> If I understand your idea correctly, the first tracer would monkeypatch 
>> `sys.settrace` so whenever someone else adds a tracer, it doesn't really do 
>> `sys.settrace` but just add a function that the real tracer would be calling 
>> after it's done tracing. But this can't really be done without the original 
>> tracer implementing it, right?
>> 
>>> On Thu, Apr 25, 2019 at 6:16 PM Ram Rachum  wrote:
>>> Oh wow, I didn't even consider that. I think you're right, I'll 
>>> do more thinking about this. Thanks Anders!
>>> 
 On Thu, Apr 25, 2019 at 6:10 PM Anders Hovmöller  
 wrote:
 Can't this be implemented today by a simple monkey patch of sys.settrace?
 
 On 25 Apr 2019, at 16:51, Ram Rachum  wrote:
 
> Hi,
> 
> Here's something I want in Python: Multiple levels of tracers working on 
> top of each other, instead of just one. 
> 
> I'm talking about the tracer that one can set by calling sys.settrace.
> 
> I've recently released PySnooper: https://github.com/cool-RR/PySnooper/
> 
> One of the difficulties I have, is that I can't debug or run the 
> `coverage` tool on the core of this module. That's because the core is a 
> trace function, and debuggers and coverage tools work by setting a trace 
> function. When PySnooper sets its trace function using `sys.settrace`, 
> the code that runs in that trace function runs without getting traced by 
> the coverage tracer.
> 
> This means that people who develop debuggers and coverage tools can't use 
> a debugger or a coverage tool on the core of their tool. It's quite an 
> annoying problem.
> 
> My proposed solution: Multiple levels of tracing, instead of just one. 
> When you install a tracer, you're not replacing the existing one, you're 
> appending a tracer to the existing list of tracers.
> 
> If this was implemented, then when PySnooper would install its tracer, 
> the coverage tracer would still be active and running, for every line of 
> code including the ones in PySnooper's tracer.
> 
> Obviously, we'll need to figure out the API and any other kind of 
> problems with this proposal.
> 
> What do you think? 
> 
> 
> Thanks,
> Ram.
> 
> 
> ___
> 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/
___
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] Idea: Allow multiple levels of tracers

2019-04-25 Thread Ram Rachum
To clarify, I meant that each trace function would manually call any trace
functions that were registered below it, instead of using the trampoline in
cpython. Does that solve the problem you raised?

On Thu, Apr 25, 2019, 20:20 Ned Batchelder  wrote:

> Perhaps I misunderstand what's implied by "simple(!) monkeypatch of
> sys.settrace", but the trickiest part of Ram's proposal is that the body of
> one trace function would still trigger the remaining trace functions.  That
> to me sounds like it's going to require changes to ceval.c
>
> --Ned.
> On 4/25/19 12:26 PM, Ram Rachum wrote:
>
> Hmm, looks like, for this to work, you'll need the existing tracer to be
> cooperative. Right now there are existing tracers, for example coverage's
> tracer and Wing IDE's tracer, and I would need to modify them for your idea
> to work, right?
>
> If I understand your idea correctly, the first tracer would monkeypatch
> `sys.settrace` so whenever someone else adds a tracer, it doesn't really do
> `sys.settrace` but just add a function that the real tracer would be
> calling after it's done tracing. But this can't really be done without the
> original tracer implementing it, right?
>
> On Thu, Apr 25, 2019 at 6:16 PM Ram Rachum  wrote:
>
>> Oh wow, I didn't even consider that. I think you're right, I'll do more
>> thinking about this. Thanks Anders!
>>
>> On Thu, Apr 25, 2019 at 6:10 PM Anders Hovmöller 
>> wrote:
>>
>>> Can't this be implemented today by a simple monkey patch of sys.settrace?
>>>
>>> On 25 Apr 2019, at 16:51, Ram Rachum  wrote:
>>>
>>> Hi,
>>>
>>> Here's something I want in Python: Multiple levels of tracers working on
>>> top of each other, instead of just one.
>>>
>>> I'm talking about the tracer that one can set by calling sys.settrace.
>>>
>>> I've recently released PySnooper: https://github.com/cool-RR/PySnooper/
>>>
>>> One of the difficulties I have, is that I can't debug or run the
>>> `coverage` tool on the core of this module. That's because the core is a
>>> trace function, and debuggers and coverage tools work by setting a trace
>>> function. When PySnooper sets its trace function using `sys.settrace`, the
>>> code that runs in that trace function runs without getting traced by the
>>> coverage tracer.
>>>
>>> This means that people who develop debuggers and coverage tools can't
>>> use a debugger or a coverage tool on the core of their tool. It's quite an
>>> annoying problem.
>>>
>>> My proposed solution: Multiple levels of tracing, instead of just one.
>>> When you install a tracer, you're not replacing the existing one, you're
>>> appending a tracer to the existing list of tracers.
>>>
>>> If this was implemented, then when PySnooper would install its tracer,
>>> the coverage tracer would still be active and running, for every line of
>>> code including the ones in PySnooper's tracer.
>>>
>>> Obviously, we'll need to figure out the API and any other kind of
>>> problems with this proposal.
>>>
>>> What do you think?
>>>
>>>
>>> Thanks,
>>> Ram.
>>>
>>>
>>> ___
>>> 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 
> listPython-ideas@python.orghttps://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] Idea: Allow multiple levels of tracers

2019-04-25 Thread Ned Batchelder
Perhaps I misunderstand what's implied by "simple(!) monkeypatch of 
sys.settrace", but the trickiest part of Ram's proposal is that the body 
of one trace function would still trigger the remaining trace 
functions.  That to me sounds like it's going to require changes to ceval.c


--Ned.

On 4/25/19 12:26 PM, Ram Rachum wrote:
Hmm, looks like, for this to work, you'll need the existing tracer to 
be cooperative. Right now there are existing tracers, for example 
coverage's tracer and Wing IDE's tracer, and I would need to modify 
them for your idea to work, right?


If I understand your idea correctly, the first tracer would 
monkeypatch `sys.settrace` so whenever someone else adds a tracer, it 
doesn't really do `sys.settrace` but just add a function that the real 
tracer would be calling after it's done tracing. But this can't really 
be done without the original tracer implementing it, right?


On Thu, Apr 25, 2019 at 6:16 PM Ram Rachum > wrote:


Oh wow, I didn't even consider that. I think you're right, I'll do
more thinking about this. Thanks Anders!

On Thu, Apr 25, 2019 at 6:10 PM Anders Hovmöller
mailto:bo...@killingar.net>> wrote:

Can't this be implemented today by a simple monkey patch of
sys.settrace?

On 25 Apr 2019, at 16:51, Ram Rachum mailto:r...@rachum.com>> wrote:


Hi,

Here's something I want in Python: Multiple levels of tracers
working on top of each other, instead of just one.

I'm talking about the tracer that one can set by calling
sys.settrace.

I've recently released PySnooper:
https://github.com/cool-RR/PySnooper/

One of the difficulties I have, is that I can't debug or run
the `coverage` tool on the core of this module. That's
because the core is a trace function, and debuggers and
coverage tools work by setting a trace function. When
PySnooper sets its trace function using `sys.settrace`, the
code that runs in that trace function runs without getting
traced by the coverage tracer.

This means that people who develop debuggers and coverage
tools can't use a debugger or a coverage tool on the core of
their tool. It's quite an annoying problem.

My proposed solution: Multiple levels of tracing, instead of
just one. When you install a tracer, you're not replacing the
existing one, you're appending a tracer to the existing list
of tracers.

If this was implemented, then when PySnooper would install
its tracer, the coverage tracer would still be active and
running, for every line of code including the ones in
PySnooper's tracer.

Obviously, we'll need to figure out the API and any other
kind of problems with this proposal.

What do you think?


Thanks,
Ram.


___
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] Idea: Allow multiple levels of tracers

2019-04-25 Thread Ram Rachum
Hmm, looks like, for this to work, you'll need the existing tracer to be
cooperative. Right now there are existing tracers, for example coverage's
tracer and Wing IDE's tracer, and I would need to modify them for your idea
to work, right?

If I understand your idea correctly, the first tracer would monkeypatch
`sys.settrace` so whenever someone else adds a tracer, it doesn't really do
`sys.settrace` but just add a function that the real tracer would be
calling after it's done tracing. But this can't really be done without the
original tracer implementing it, right?

On Thu, Apr 25, 2019 at 6:16 PM Ram Rachum  wrote:

> Oh wow, I didn't even consider that. I think you're right, I'll do more
> thinking about this. Thanks Anders!
>
> On Thu, Apr 25, 2019 at 6:10 PM Anders Hovmöller 
> wrote:
>
>> Can't this be implemented today by a simple monkey patch of sys.settrace?
>>
>> On 25 Apr 2019, at 16:51, Ram Rachum  wrote:
>>
>> Hi,
>>
>> Here's something I want in Python: Multiple levels of tracers working on
>> top of each other, instead of just one.
>>
>> I'm talking about the tracer that one can set by calling sys.settrace.
>>
>> I've recently released PySnooper: https://github.com/cool-RR/PySnooper/
>>
>> One of the difficulties I have, is that I can't debug or run the
>> `coverage` tool on the core of this module. That's because the core is a
>> trace function, and debuggers and coverage tools work by setting a trace
>> function. When PySnooper sets its trace function using `sys.settrace`, the
>> code that runs in that trace function runs without getting traced by the
>> coverage tracer.
>>
>> This means that people who develop debuggers and coverage tools can't use
>> a debugger or a coverage tool on the core of their tool. It's quite an
>> annoying problem.
>>
>> My proposed solution: Multiple levels of tracing, instead of just one.
>> When you install a tracer, you're not replacing the existing one, you're
>> appending a tracer to the existing list of tracers.
>>
>> If this was implemented, then when PySnooper would install its tracer,
>> the coverage tracer would still be active and running, for every line of
>> code including the ones in PySnooper's tracer.
>>
>> Obviously, we'll need to figure out the API and any other kind of
>> problems with this proposal.
>>
>> What do you think?
>>
>>
>> Thanks,
>> Ram.
>>
>>
>> ___
>> 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] Idea: Allow multiple levels of tracers

2019-04-25 Thread Ram Rachum
Oh wow, I didn't even consider that. I think you're right, I'll do more
thinking about this. Thanks Anders!

On Thu, Apr 25, 2019 at 6:10 PM Anders Hovmöller 
wrote:

> Can't this be implemented today by a simple monkey patch of sys.settrace?
>
> On 25 Apr 2019, at 16:51, Ram Rachum  wrote:
>
> Hi,
>
> Here's something I want in Python: Multiple levels of tracers working on
> top of each other, instead of just one.
>
> I'm talking about the tracer that one can set by calling sys.settrace.
>
> I've recently released PySnooper: https://github.com/cool-RR/PySnooper/
>
> One of the difficulties I have, is that I can't debug or run the
> `coverage` tool on the core of this module. That's because the core is a
> trace function, and debuggers and coverage tools work by setting a trace
> function. When PySnooper sets its trace function using `sys.settrace`, the
> code that runs in that trace function runs without getting traced by the
> coverage tracer.
>
> This means that people who develop debuggers and coverage tools can't use
> a debugger or a coverage tool on the core of their tool. It's quite an
> annoying problem.
>
> My proposed solution: Multiple levels of tracing, instead of just one.
> When you install a tracer, you're not replacing the existing one, you're
> appending a tracer to the existing list of tracers.
>
> If this was implemented, then when PySnooper would install its tracer, the
> coverage tracer would still be active and running, for every line of code
> including the ones in PySnooper's tracer.
>
> Obviously, we'll need to figure out the API and any other kind of problems
> with this proposal.
>
> What do you think?
>
>
> Thanks,
> Ram.
>
>
> ___
> 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] Idea: Allow multiple levels of tracers

2019-04-25 Thread Anders Hovmöller
Can't this be implemented today by a simple monkey patch of sys.settrace?

> On 25 Apr 2019, at 16:51, Ram Rachum  wrote:
> 
> Hi,
> 
> Here's something I want in Python: Multiple levels of tracers working on top 
> of each other, instead of just one. 
> 
> I'm talking about the tracer that one can set by calling sys.settrace.
> 
> I've recently released PySnooper: https://github.com/cool-RR/PySnooper/
> 
> One of the difficulties I have, is that I can't debug or run the `coverage` 
> tool on the core of this module. That's because the core is a trace function, 
> and debuggers and coverage tools work by setting a trace function. When 
> PySnooper sets its trace function using `sys.settrace`, the code that runs in 
> that trace function runs without getting traced by the coverage tracer.
> 
> This means that people who develop debuggers and coverage tools can't use a 
> debugger or a coverage tool on the core of their tool. It's quite an annoying 
> problem.
> 
> My proposed solution: Multiple levels of tracing, instead of just one. When 
> you install a tracer, you're not replacing the existing one, you're appending 
> a tracer to the existing list of tracers.
> 
> If this was implemented, then when PySnooper would install its tracer, the 
> coverage tracer would still be active and running, for every line of code 
> including the ones in PySnooper's tracer.
> 
> Obviously, we'll need to figure out the API and any other kind of problems 
> with this proposal.
> 
> What do you think? 
> 
> 
> Thanks,
> Ram.
> 
> 
> ___
> 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] Idea: Allow multiple levels of tracers

2019-04-25 Thread Ram Rachum
Hi,

Here's something I want in Python: Multiple levels of tracers working on
top of each other, instead of just one.

I'm talking about the tracer that one can set by calling sys.settrace.

I've recently released PySnooper: https://github.com/cool-RR/PySnooper/

One of the difficulties I have, is that I can't debug or run the `coverage`
tool on the core of this module. That's because the core is a trace
function, and debuggers and coverage tools work by setting a trace
function. When PySnooper sets its trace function using `sys.settrace`, the
code that runs in that trace function runs without getting traced by the
coverage tracer.

This means that people who develop debuggers and coverage tools can't use a
debugger or a coverage tool on the core of their tool. It's quite an
annoying problem.

My proposed solution: Multiple levels of tracing, instead of just one. When
you install a tracer, you're not replacing the existing one, you're
appending a tracer to the existing list of tracers.

If this was implemented, then when PySnooper would install its tracer, the
coverage tracer would still be active and running, for every line of code
including the ones in PySnooper's tracer.

Obviously, we'll need to figure out the API and any other kind of problems
with this proposal.

What do you think?


Thanks,
Ram.
___
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] Open parenthesis in REPL completion

2019-04-25 Thread Stefano Borini
My two cents as well.
I also find the open parenthesis very annoying. For me, it's asymmetry
with PyCharm behavior, and inconsistency with bash.

PyCharm adds the parenthesis, but also adds the end parenthesis, so
the whole use of parentheses is consistent: the user has not to worry
about them.
Bash refuses to guess when it's ambiguous, and stops until you fill
the ambiguous part.

Right now, the REPL implements a mixed situation where it both assumes
your usage, and does not help you all the way through. Although we can
all agree that functions most of the time are invoked, rather than
used as is.
IMHO, either the parenthesis should not be added, or two parentheses
should be added and the cursor placed in the center (I am unsure about
the details of the REPL implementation, but I guess it's possible) at
least to have a consistent experience.



On Thu, 25 Apr 2019 at 14:24, Jonathan Fine  wrote:
>
> This is an interesting thread. Here's my two cents worth. (Colloquial US 
> English for a low-value opinion.)
>
> I'm in favour of sensible defaults (of course). In this situation, perhaps 
> this means defaults that work well for those who would find it difficult to 
> select a different default. Put enough way, values that work well for Emacs 
> users should not be the default (unless they also work well for beginners).
>
> Sometimes, when I'm using a module for the first time (or when I'm puzzled 
> about Python's behaviour and online documentation), I find myself doing
> >>> help(something)
> quite often. And I find myself typing
> >>> help({})
> instead of
> >>> help(dict)
> to avoid the unwanted
> >>> help(dict(
>
> My preference, which might work well for a wide range of use cases, is
> 1. If the initial identifier is help, tab produces the opening paren (.
> 2. If the intial identifier is callable, tab produces the opening paren (.
> 3. After help(, tab does not produce opening paren (.
> 4. Otherwise, tab does produce opening paren (.
> 5. Perhaps, after something like
> >>> help(int
> have tab produce the CLOSING paren ).
>
> As I said, just my two cents worth. Your opinions may vary.
>
> --
> 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/



-- 
Kind regards,

Stefano Borini
___
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] Open parenthesis in REPL completion

2019-04-25 Thread Jonathan Fine
This is an interesting thread. Here's my two cents worth. (Colloquial US
English for a low-value opinion.)

I'm in favour of sensible defaults (of course). In this situation, perhaps
this means defaults that work well for those who would find it difficult to
select a different default. Put enough way, values that work well for Emacs
users should not be the default (unless they also work well for beginners).

Sometimes, when I'm using a module for the first time (or when I'm puzzled
about Python's behaviour and online documentation), I find myself doing
>>> help(something)
quite often. And I find myself typing
>>> help({})
instead of
>>> help(dict)
to avoid the unwanted
>>> help(dict(

My preference, which might work well for a wide range of use cases, is
1. If the initial identifier is help, tab produces the opening paren (.
2. If the intial identifier is callable, tab produces the opening paren (.
3. After help(, tab does not produce opening paren (.
4. Otherwise, tab does produce opening paren (.
5. Perhaps, after something like
>>> help(int
have tab produce the CLOSING paren ).

As I said, just my two cents worth. Your opinions may vary.

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


Re: [Python-ideas] Open parenthesis in REPL completion

2019-04-25 Thread Rhodri James

On 25/04/2019 12:27, Stephen J. Turnbull wrote:

Steven D'Aprano writes:

  > But having the opening bracket auto-added is a small satisfaction,

I'm not going to weigh in on this feature: I can see it either way.
What I don't get is why we don't go full metal Emacs, by adding the
corresponding end delimiter, and backspace.  In each line below the
RHS are the characters typed, the LHS the characters inserted, and the
vertical bar | represents the position of the insertion cursor:

(   => (|)
[   => [|]
{   => {|}
"   => "|"
""  => ""|# fooled ya, didn't I?  Could do it for parens too.
""" => """|"""
''  => ''|
''' => '''|'''

There may be others.  And bonus points for DTRT in strings and
comments (especially for "'", since it's used as apostrophe in
non-program text).

Once I got used to it, I found it really cut down on the annoyance of
counting parens and making sure start parens weren't paired with end
braces and similar errors.  YMMV, of course.


My mileage definitely varies.  This sort of autocompletion is the first 
thing I turn off in the Eclipse-variants that come bundled with a lot of 
the SDKs I use, and I've never enabled it in EMACs.  Automatically 
highlighting where the matching brackets or quotes are is a lovely 
thing, but I like making my own decisions and stepping past or deleting 
decisions the editor has made for me is a pain.



--
Rhodri James *-* Kynesim Ltd
___
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] Open parenthesis in REPL completion

2019-04-25 Thread Stephen J. Turnbull
Steven D'Aprano writes:

 > But having the opening bracket auto-added is a small satisfaction,

I'm not going to weigh in on this feature: I can see it either way.
What I don't get is why we don't go full metal Emacs, by adding the
corresponding end delimiter, and backspace.  In each line below the
RHS are the characters typed, the LHS the characters inserted, and the
vertical bar | represents the position of the insertion cursor:

(   => (|)
[   => [|]
{   => {|}
"   => "|"
""  => ""|# fooled ya, didn't I?  Could do it for parens too.
""" => """|"""
''  => ''|
''' => '''|'''

There may be others.  And bonus points for DTRT in strings and
comments (especially for "'", since it's used as apostrophe in
non-program text).

Once I got used to it, I found it really cut down on the annoyance of
counting parens and making sure start parens weren't paired with end
braces and similar errors.  YMMV, of course.

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] Open parenthesis in REPL completion

2019-04-25 Thread Steven D'Aprano
On Fri, Apr 19, 2019 at 05:12:06PM -0300, Danilo J. S. Bellini wrote:

> I'm not aware if that was already discussed, but something I find quite
> annoying is the REPL auto-complete that also includes the open parenthesis
> symbol. I think it shouldn't be included in TAB completion. At least twice
> a week I make mistakes like typing "help(something()" with unmatched
> parentheses

You could try reading the command line before hitting Enter *wink*

I know what you mean, and it's a tiny annoyance for me too that when I 
type "help(function(" I have to delete the autocompleted opening 
bracket. So I guess that's a small annoyance a few dozen times a day.

But having the opening bracket auto-added is a small satisfaction, and 
if you're using the REPL for actual calculations and not just help(), 
the benefit probably outweighs the annoyance:

# save up to four opening brackets
result = function(myclass(arg)) + another(x).method()


So I don't think that have the extra complication of a switch to turn 
this feature off is a good idea.



-- 
Steven
___
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 a `dir_fd` parameter to `os.truncate`?

2019-04-25 Thread Steven D'Aprano
On Fri, Apr 19, 2019 at 09:49:54PM +0200, Sebastian M. Ernst wrote:
> Hi everyone,
> 
> many methods in `os` have a `dir_fd` parameter, for instance `unlink` [1]:
> ```python
> os.unlink(path, *, dir_fd=None)
> ```
> 
> The `dir_fd` parameter [2] allows it to describe paths relative to
> directory descriptors. Otherwise, relative paths are relative to the
> current working directory.
> 
> The implementation of `truncate` in `os` does not have this parameter [3]:
> ```python
> os.truncate(path, length)
> ```

[...]
> Why not add a convenience function or wrapper like above to the `os`
> module, which closes this gap and is more consistent with other methods?

I haven't seen any responses to your proposal, perhaps I missed 
something.

The os module is supposed to be a thin wrapper around the os 
functionality, but your wrapper seems thin enough that I think it could 
and should just go into the os.truncate function itself, rather than 
adding a new function.



-- 
Steven
___
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] What are the strong use cases for str.rindex()? (John Lin)

2019-04-25 Thread Steven D'Aprano
On Wed, Apr 24, 2019 at 01:50:48AM +0800, Thautwarm Zhao wrote:

> However, the reason why we don't need list.rindex but do for str.rindex is
> simple I'd say: str is immutable and has no O(1) reverse method.
> 
> On the other hand, when it comes to list, you can use list.index after
> list.reverse, and after a bunch of operations you can resume the state by
> invoking list.reverse again.

list reverse is not O(1), and flipping the order, then flipping the 
order back again is not safe if the list could be accessed by two or 
more threads.

(The call to reverse itself is thread-safe, but not the operations in 
between.)


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