swagger-api / swagger-api/swagger-codegen

[Python] Local variable conflict in mustache boilerplate

Open
#9,618 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Mustache
Stars
17.8k
Forks
6k
PR merge metrics
No merged PRs in 30d

Description

Description

The mustache template for the Python API uses local variable names that conflict with common API parameters. The template code that extracts keyword parameters and merges them with the local-variable dictionary -- which is populated from locals() -- is implemented using local variable names that are unprefixed, and thereby conflict with passed positional parameters.

Thus, for example, if the API defines a parameter named key (a common API parameter name), it erroneously gets assigned the value for the first keyword argument extracted rather than using the value it was passed positionally because the local variable named key is used in the keyword-argument iterator.

This is also true for any other local variables defined in the function prior to the assignment in that processing loop (e.g., params, val, kwargs, etc.) .

Swagger-codegen version

Pertains to any version, including the latest (3.0.10).

Swagger declaration file content or url
{
    "swagger": "2.0",
    "basePath": "/api/v1",
    "paths": {
        "/device/press_key": {
            "post": {
                    "204": {
                        "description": "Success"
                    }
                },
                "operationId": "post_press_key",
                "parameters": [
                    {
                        "name": "key",
                        "in": "query",
                        "type": "string",
                        "required": true,
                    }
                ],
                "tags": [
                    "device"
                ]
            }
        }
    }
}

The template generates code like this:

def post_press_key_with_http_info(self, key, **kwargs):  # noqa: E501
    ...
    for key, val in six.iteritems(params['kwargs']):
        ...
        params[key] = val   # <--- `key` here is loop variable instead of func param
    ...

which results in the value for key becoming clobbered by the loop variable by the time it gets transferred into query_params subsequently.

Command line used for generation
swagger-codegen generate --lang python
Steps to reproduce

self-evident

Related issues/PRs

This same deficiency was, in fact, reported in #8332 -- in that case pertaining to the API variable params -- but that issue was closed without any fix being enacted.

Suggest a fix/enhancement

Use _-prefixed or __-prefixed variable names for all local variables used in processing prior to the params dictionary becoming finalized. Then, only API parameters having unscore-prefixed names would remain as conflicts, but such names for public API parameters are ill-advised in the first place.

Module imports should also similarly use aliases:

import re as _re
import six as _six
  ...

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Python API mustache template and generate an API using the supplied Swagger declaration with swagger-codegen generate --lang python. Update the generated function's local processing names and imports so API parameters are not clobbered, then verify the generated post_press_key_with_http_info behavior with the example parameter names.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.