starlette icon indicating copy to clipboard operation
starlette copied to clipboard

Update schemas.py

Open gansik opened this issue 1 year ago β€’ 5 comments

Overwriting an iterated variable inside a loop

Summary

The easiest way to describe the problem is to simply quote the code:

for route in routes:
    routes = route.routes or []
    ...

Checklist

  • [x] I understand that this PR may be closed in case there was no previous discussion. (This doesn't apply to typos!)
  • [x] I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • [x] I've updated the documentation accordingly.

gansik avatar Oct 04 '24 14:10 gansik

Thanks @gansik :)

Would you like to add a more meaningful PR title?

Kludex avatar Oct 09 '24 10:10 Kludex

Would you like to add a more meaningful PR title?

I've added more information. This is my first PR in open source, sorry about that

gansik avatar Oct 09 '24 18:10 gansik

Can you show me an MRE that this code solves?

Kludex avatar Oct 13 '24 19:10 Kludex

Can you show me an MRE that this code solves?

If you use a different order of routing rules in the example from the documentation, then β€œRoute(β€˜/’, homepage)” will not be in the generated json schema

routes = [
    Mount('/users', routes=[
        Route('/', users, methods=['GET', 'POST']),
        Route('/{username}', user),
    ]),
    Route('/', homepage)
]

gansik avatar Oct 16 '24 14:10 gansik

Can you show me an MRE that this code solves?

If you use a different order of routing rules in the example from the documentation, then β€œRoute(β€˜/’, homepage)” will not be in the generated json schema

routes = [
    Mount('/users', routes=[
        Route('/', users, methods=['GET', 'POST']),
        Route('/{username}', user),
    ]),
    Route('/', homepage)
]

Can you show me the whole code that I can run and see the difference in behavior? I want to add a test...

Kludex avatar Oct 18 '24 08:10 Kludex

Ping @gansik πŸ‘€

Kludex avatar Nov 22 '24 12:11 Kludex

Although the proposed change is definitely clearer in its intent, I don't think a bug exists with the current implementation due to variable scoping. Here is a simple script to illustrate:

lst = ["A", "B", "C"]

for outer_item in lst:
    print(outer_item)

    # overriding `lst` doesn't affect the outer loop
    lst = [1, 2, 3]

    for inner_item in lst:
        print(inner_item)

I tried to reproduce the bug from https://github.com/encode/starlette/pull/2717#issuecomment-2416961253 in a test but couldn't. Everything seems to work fine when mounted routes come before the root mount (I just reused existing handlers from test_schemas.py):

def test_schema_endpoint_pr_example(test_client_factory: TestClientFactory) -> None:
    app = Starlette(
        routes=[
            Mount(
                "/users",
                routes=[
                    Route("/", list_users, methods=["GET"]),
                    Route("/{username}", get_user),
                ],
            ),
            Route("/", OrganisationsEndpoint),
            Route("/schema", endpoint=schema, methods=["GET"], include_in_schema=False),
        ]
    )
    client = test_client_factory(app)
    response = client.get("/schema")

    value = response.text.strip()
    expected = """
    info:
      title: Example API
      version: '1.0'
    openapi: 3.0.0
    paths:
      /:
        get:
          responses:
            200:
              description: A list of organisations.
              examples:
              - name: Foo Corp.
              - name: Acme Ltd.
        post:
          responses:
            200:
              description: An organisation.
              examples:
                name: Foo Corp.
      /users/:
        get:
          responses:
            200:
              description: A list of users.
              examples:
              - username: tom
              - username: lucy
      /users/{username}:
        get:
          responses:
            200:
              description: A user.
              examples:
                username: tom
    """.strip()

    assert value == expected

logan-connolly avatar Nov 23 '24 19:11 logan-connolly