How to get a feedback on Python idea?

Disclaimer: I do not follow Python world. This is the best place I found to ask. Please forgive me if it’s misplaced.

Hi community, is there any “authority” in Python world where people can share Python ideas – submit an idea, get some feedback if it’s known in the community / worth propagating etc? I have one such idea and asked people around me if they knew it – they did not. I have written it on my github page, but would like to find some Python authority to tell me what they think (even if it be “that’s already widely adopted for years”). What can be the best place / the best way to ask? For example, the C++ shares some articles which may be interesting for the community – new “trick”, a standard thing nicely explained etc; they must have some selection process for this. Does Python world have something similar?

Thanks for your answer.
This is meant as a question if there is some central place to submit ideas, not asking about the idea itself.

Welcome to the community! You’ve already found one place where you can submit ideas: this Discourse category. Feel free to write a post here outlining your idea, and if there’s enough support (and you can find a core dev to sponsor it), the next step would be a PEP. You can also use the python-ideas@ mailing list, but it can get a bit overwhelming.

Thanks for your answer! What I mean is not a proposal to Python itself, rather a “trick” to use existing Python lang features: “with” resource management combined with coroutines to get RAII – no core dev needed to support this :slight_smile: If I understand correctly what PEPs are, this is not a proposal trying to find its way to PEP.

OK, the idea is to use coroutine trampolining to avoid nesting for multiple “with statement”, in other words, achieve an RAII-like “flat” exception-safe code in Python. I did some research on Google if this is a known pattern and was not able to find any supportive evidence. So it’s not a proposal for Python itself, rather an idea to combine its expressive powers in a maybe new way which can solve some real problems I have seen in Python codebases I’ve met.

But again, this thread is not meant as a self-promo, it’s a question if there is anyone to contact in Python community, something like isocpp editors in C++ world. But if you glance over the idea and let me know, it would be great of course :slight_smile: Thanks in advance for your time

1 Like

I’m not aware of anything like that, but it sounds like a great idea. I hope someone can either point out somwehere that can be used to share ideas like this, or set something up :slightly_smiling_face:

Interesting! One alternative is to use contextlib.ExitStack:

def program():
    with ExitStack() as stack:
        r1 = stack.enter_context(resource1())
        r2 = stack.enter_context(resource2())
        ...
1 Like

This looks quite neat, and nicely written up! It reminds me a lot of pytest fixtures.

I guess one downside is that you have to define a generator function for the nested with block, and then ‘execute’ that generator code from elsewhere. I could imagine this being useful for a program that acquires lots of resources all at once, but for regular use it might be unwanted noise.

The other main downside is code readability, since this isn’t something that’s seen in the wild very often as far as I’m aware!

I’d be interested to play around with it, perhaps if the run() function were packaged up in a small package on PyPI.

@LewisGaul The downsides of turning a plain function to a resource-aware generator function, and the need to execute from elsewhere (from the trampoline folding the “with” blocks) are definitely there. For an example program which just open()s a file under a with statement and writes to it, this would definitely be an overkill. I really value “explicit is better than implicit” and KISS where possible, but there may be use cases where not employing some resource management abstraction (RAII, IO monadic Resource) would yield some kind of spaghetti code / copy-paste code. Let me explain: The motivation for me to explore this was a use case for which it is crucial to gradually acquire multiple resources and finally release them (in the right, reversed order) – and ideally within a single “def” block (for w/e reasons). The level of nesting can be about 10 levels, written “naively” with “with” would shift the effective code by 40 spaces.

@Jelle thanks for pointing out to enter_context(), did not know about that.

Any more proposals where to ask would be most welcome, or spreading the link further :slight_smile: Thank you!

I may be missing the point, but there is no need to nest context managers if they have the same scope:

import contextlib

@contextlib.contextmanager
def foo(arg):
    print(f'initializing {arg}')
    yield arg
    print(f'finalizing {arg}')

with (foo(1) as a,
      foo(2) as b,
      foo(3) as c):
    print(a, b, c)

or

with foo(1) as a, foo(2) as b, foo(3) as c:
    print(a, b, c)

with syntax valid for python versions older than 3.10.

If the context managers have different scope, I think the nested indent structure is a actually a very nice visual indicator of the code structure. If the resulting indent is excessive, it may indicate that the code needs to be refactored in easier to understand units, similarly to the case where there are too many nested conditional structures.

Hi, I see your point with code like

with make_res1(...) as a, make_res2(...) as b, make_res3(...) as c:
    ... # use a,b,c here

The problem with this is that it’s quite difficult to put a “custom” code between make_res1() and make_res2(), between make_res2() and make_res3() etc. What if I need about five lines of code to “compute” an argument for make_res2, given a as the input?

Something which in my idea would be written as

def program():
    a = yield make_resource1()
    ... # five more lines which now have access to the acquired `a`
        # which result in a variable `a1`
    b = yield make_resource2(a1)
    ... # few more lines which have access to both `a` and `b`
        # which result in a variable `b1`
    c = yield make_resource3(b1)
    ... # 5x the same as above
    
    ... # use the variables a,b,c,d,e...

    # ...,e,d,c,b,a "unroll" automatically at the end of block

My example of such code (my motivation for exploring this area) could be

def test_functional_test_case():
    a = create_a(name='a')  # create an entity of type A via REST POST
    all_as = list_as()  # list all known As via REST GET
    assert len(all_as) == 1  # assert the system has only one entity of type A
    assert all_as[0].name == 'a'  # assert the POST respects the supplied name

    b = create_b(a_id=a.id)  # create an entity of type B via REST POST
    assert b.a_id == a.id  # the POST respects the linking to the instance of A

    ...  # more nested resources, more asserts

    # the most recently acquired resource is released here
    # ....
    # DELETE b
    # DELETE a

I know it’s possible to restructure the code like

with make_res1(...) as a,
     asserts_and_make_res2_(...) as b,
     asserts_make_res3(...) as c:
    pass

but this require much more writing for each test case. The ultimate goal is to create a terse, nice syntax for each test which is just a “script” running some scenario, and needs to cleanup after itself at the end (even if some assert fails).

I hope this makes clear why I would like to avoid nesting withs, either explicitely, or by using multiple resource managers within single with statement.