Update schemas.py
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.
Thanks @gansik :)
Would you like to add a more meaningful PR title?
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
Can you show me an MRE that this code solves?
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 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...
Ping @gansik π
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