classification
Title: Confirm the types of parameters of traceback.format_list and traceback.StackSummary.from_list post-3.5
Type: behavior Stage:
Components: Documentation Versions: Python 3.8, Python 3.7, Python 3.6, Python 3.5
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: docs@python Nosy List: Nathaniel Manista, berker.peksag, docs@python, srittau
Priority: normal Keywords:

Created on 2018-09-12 20:03 by Nathaniel Manista, last changed 2018-09-20 17:16 by berker.peksag.

Messages (5)
msg325175 - (view) Author: Nathaniel Manista (Nathaniel Manista) Date: 2018-09-12 20:03
So I'm fixing a bug in typeshed's accounting of the traceback module (https://github.com/python/typeshed/pull/2436) and the documented semantics of traceback.format_list don't quite smell to me what I think they might be intended to be:

1) I know it has the name "format_list", but is it really intended to require a list? Why not a sequence, or a collection, or an iterable? I would think it would be fine to pass an iterable to traceback.format_list. Is it fine?

2) What is the desired component type for the aggregate passed to format_list? In 3.4-and-earlier it was Tuple[str, int, str, Optional[str]], and that still works in 3.5-through-3.8, but is that just backwards compatibility or is that something that users of traceback.format_list should feel encouraged to continue passing into the future?

Sorry for filing a bug just to ask "huh; really?" but... please confirm?
msg325176 - (view) Author: Nathaniel Manista (Nathaniel Manista) Date: 2018-09-12 20:29
... and while we're here, how about StackSummary.from_list's "a_list" parameter as well:

3) Can it be Iterable? It looks like it can be Iterable? Is it fine for it to be Iterable?

4) Should the component type of "a_list" be FrameSummary? Is the support for Tuple[str, int, str, Optional[str]] merely backward-looking, or is new code encouraged to pass Tuple[str, int, str, Optional[str]] objects?
msg325313 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2018-09-14 00:14
> 1) I know it has the name "format_list", but is it really intended to require a
> list? Why not a sequence, or a collection, or an iterable? I would think it would
> be fine to pass an iterable to traceback.format_list. Is it fine?

In 3.4, format_list() was documented to accept return values of extract_tb() and extract_stack() functions and they both were returned lists:

    def extract_tb(tb, limit=None):
        return list(_extract_tb_iter(tb, limit=limit))

    def extract_stack(f=None, limit=None):
        stack = list(_extract_stack_iter(_get_stack(f), limit=limit))
        stack.reverse()
        return stack

I don't think we support the "pass manually created iterables" case here.

> 2) What is the desired component type for the aggregate passed to
> format_list? In 3.4-and-earlier it was Tuple[str, int, str,
> Optional[str]], and that still works in 3.5-through-3.8, but is that
> just backwards compatibility [...]

Yes, the old API is still supported for backwards compatibility reasons.
msg325895 - (view) Author: Nathaniel Manista (Nathaniel Manista) Date: 2018-09-20 16:09
> In 3.4, format_list() was documented to accept return values of extract_tb() > and extract_stack() functions and they both were returned lists:
> 
>     def extract_tb(tb, limit=None):
>         return list(_extract_tb_iter(tb, limit=limit))
> 
>     def extract_stack(f=None, limit=None):
>         stack = list(_extract_stack_iter(_get_stack(f), limit=limit))
>         stack.reverse()
>         return stack

I think that’s an unnecessarily and extraordinarily narrow reading - you could use the same reading to make a judgement of “format_list may only be passed values returned by extract_tb and extract_stack rather than other values of the same type”, and that would be absurd.

I don’t think it’s a wise choice to say “because the motivation for offering the format_list function was to work with values returned by extract_tb and extract_stack, the allowed inputs to format_list should be restricted to just those types”.

Why not support Iterable[FrameSummary]? A choice to support Iterable[FrameSummary] *is also a choice to support List[FrameSummary]*. It's just a "wider" choice; it’s not a breaking choice to drop support for List[FrameSummary].

> I don't think we support the "pass manually created iterables" case here.

What’s a “manually created iterable”? What kinds of iterables aren’t “manually created iterables”? Can their differences be captured in the type system?

> Yes, the old API is still supported for backwards compatibility reasons.

This is a very flat statement that invites questions by what it doesn’t say and by the way it describes something that is true today without saying for how long into the future that thing will remain true. For how long will the old API be supported for backwards compatibility reasons? Is new code encouraged to use the new API? If the new API is better, shouldn’t new code use it? If the new API isn’t better, why was it introduced?
msg325911 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2018-09-20 17:16
> Why not support Iterable[FrameSummary]?

The question that needs to be answered here is "why we should support Iterable[FrameSummary]?" and you're one the one who needs to answer it instead of saying our design decisions were "absurd" and "not wise", without giving any concrete use cases for your "wider" design choice.

Initial docstring for format_list() were added in 2000: https://github.com/python/cpython/commit/e7b146fb3bdca62a0d5ecc06dbf3348e5a4fe757#diff-e57ff53a569d0ebbe201ad0c102ee27e

    Given a list of tuples as returned by extract_tb() or
    extract_stack(), return a list of strings ready for printing.

There are no tests for iterables other than list at https://github.com/python/cpython/blob/master/Lib/test/test_traceback.py 

So we won't change documentation and docstrings, add more tests without seeing concrete use cases.

> What’s a “manually created iterable”?

I meant an iterable that is extracted from a traceback object manually without using extract_tb() or extract_stack() functions (by using a custom function, an external dependency, or HTTP API) How people can get Iterable[FrameSummary] as an input and pass it to format_list()?

> For how long will the old API be supported for backwards
> compatibility reasons?

I don't remember any plans to remove the support for the old API. And I'm pretty sure we won't do anything until 2.7 is out of maintenance.

> Is new code encouraged to use the new API? If the new API is better,
> shouldn’t new code use it? If the new API isn’t better, why was it
> introduced?

Are you serious? No, we've introduced the new API and spent weeks designing it just to play with people. They should stick with the old one for no reason.
History
Date User Action Args
2018-09-20 17:16:37berker.peksagsetmessages: + msg325911
2018-09-20 16:09:59Nathaniel Manistasetmessages: + msg325895
2018-09-14 00:14:28berker.peksagsetnosy: + berker.peksag
messages: + msg325313
2018-09-13 00:00:59srittausetnosy: + srittau
2018-09-12 20:29:15Nathaniel Manistasetmessages: + msg325176
title: Confirm the type of traceback.format_list post-3.5 -> Confirm the types of parameters of traceback.format_list and traceback.StackSummary.from_list post-3.5
2018-09-12 20:03:24Nathaniel Manistacreate