diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java index 1bc95cfdd67..e4bf48e9d5b 100755 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/PythonClientCodegen.java @@ -3,15 +3,21 @@ package io.swagger.codegen.languages; import io.swagger.codegen.CliOption; import io.swagger.codegen.CodegenConfig; import io.swagger.codegen.CodegenConstants; +import io.swagger.codegen.CodegenModel; import io.swagger.codegen.CodegenParameter; +import io.swagger.codegen.CodegenProperty; import io.swagger.codegen.CodegenType; import io.swagger.codegen.DefaultCodegen; import io.swagger.codegen.SupportingFile; import io.swagger.models.properties.*; import java.io.File; +import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; +import java.util.List; +import java.util.Map; import org.apache.commons.lang.StringUtils; @@ -21,6 +27,8 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig protected String apiDocPath = "docs/"; protected String modelDocPath = "docs/"; + protected Map regexModifiers; + private String testFolder; public PythonClientCodegen() { @@ -87,6 +95,14 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig "assert", "else", "if", "pass", "yield", "break", "except", "import", "print", "class", "exec", "in", "raise", "continue", "finally", "is", "return", "def", "for", "lambda", "try", "self")); + + regexModifiers = new HashMap(); + regexModifiers.put('i', "IGNORECASE"); + regexModifiers.put('l', "LOCALE"); + regexModifiers.put('m', "MULTILINE"); + regexModifiers.put('s', "DOTALL"); + regexModifiers.put('u', "UNICODE"); + regexModifiers.put('x', "VERBOSE"); cliOptions.clear(); cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "python package name (convention: snake_case).") @@ -143,6 +159,46 @@ public class PythonClientCodegen extends DefaultCodegen implements CodegenConfig private static String dropDots(String str) { return str.replaceAll("\\.", "_"); } + + @Override + public void postProcessParameter(CodegenParameter parameter){ + postProcessPattern(parameter.pattern, parameter.vendorExtensions); + } + + @Override + public void postProcessModelProperty(CodegenModel model, CodegenProperty property) { + postProcessPattern(property.pattern, property.vendorExtensions); + } + + /* + * The swagger pattern spec follows the Perl convention and style of modifiers. Python + * does not support this in as natural a way so it needs to convert it. See + * https://docs.python.org/2/howto/regex.html#compilation-flags for details. + */ + public void postProcessPattern(String pattern, Map vendorExtensions){ + if(pattern != null) { + int i = pattern.lastIndexOf('/'); + + //Must follow Perl /pattern/modifiers convention + if(pattern.charAt(0) != '/' || i < 2) { + throw new IllegalArgumentException("Pattern must follow the Perl " + + "/pattern/modifiers convention. "+pattern+" is not valid."); + } + + String regex = pattern.substring(1, i).replace("'", "\'"); + List modifiers = new ArrayList(); + + for(char c : pattern.substring(i).toCharArray()) { + if(regexModifiers.containsKey(c)) { + String modifier = regexModifiers.get(c); + modifiers.add(modifier); + } + } + + vendorExtensions.put("x-regex", regex); + vendorExtensions.put("x-modifiers", modifiers); + } + } @Override public CodegenType getTag() { diff --git a/modules/swagger-codegen/src/main/resources/python/api.mustache b/modules/swagger-codegen/src/main/resources/python/api.mustache index 399c7f58451..94458e3f724 100644 --- a/modules/swagger-codegen/src/main/resources/python/api.mustache +++ b/modules/swagger-codegen/src/main/resources/python/api.mustache @@ -116,7 +116,7 @@ class {{classname}}(object): raise ValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, must be a value greater than or equal to `{{minimum}}`") {{/minimum}} {{#pattern}} - if '{{paramName}}' in params and not re.match('{{pattern}}', params['{{paramName}}']): + if '{{paramName}}' in params and not re.search('{{vendorExtensions.x-regex}}', params['{{paramName}}']{{#vendorExtensions.x-modifiers}}{{#-first}}, flags={{/-first}}re.{{.}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}): raise ValueError("Invalid value for parameter `{{paramName}}` when calling `{{operationId}}`, must conform to the pattern `{{pattern}}`") {{/pattern}} {{/hasValidation}} diff --git a/modules/swagger-codegen/src/main/resources/python/model.mustache b/modules/swagger-codegen/src/main/resources/python/model.mustache index 0cb98a57ef0..e62fa2cbf66 100644 --- a/modules/swagger-codegen/src/main/resources/python/model.mustache +++ b/modules/swagger-codegen/src/main/resources/python/model.mustache @@ -103,7 +103,7 @@ class {{classname}}(object): raise ValueError("Invalid value for `{{name}}`, must be a value greater than or equal to `{{minimum}}`") {{/minimum}} {{#pattern}} - if not re.match('{{pattern}}', {{name}}): + if not re.search('{{vendorExtensions.x-regex}}', {{name}}{{#vendorExtensions.x-modifiers}}{{#-first}}, flags={{/-first}}re.{{.}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}): raise ValueError("Invalid value for `{{name}}`, must be a follow pattern or equal to `{{pattern}}`") {{/pattern}} {{/hasValidation}} diff --git a/samples/client/petstore/python/README.md b/samples/client/petstore/python/README.md index 990d5e53651..3cdf5029787 100644 --- a/samples/client/petstore/python/README.md +++ b/samples/client/petstore/python/README.md @@ -5,7 +5,7 @@ This Python package is automatically generated by the [Swagger Codegen](https:// - API version: 1.0.0 - Package version: 1.0.0 -- Build date: 2016-05-06T22:43:12.044+01:00 +- Build date: 2016-05-09T01:08:25.311+01:00 - Build package: class io.swagger.codegen.languages.PythonClientCodegen ## Requirements. diff --git a/samples/client/petstore/python/swagger_client/apis/fake_api.py b/samples/client/petstore/python/swagger_client/apis/fake_api.py index ba79874f6c7..5d3903b2d21 100644 --- a/samples/client/petstore/python/swagger_client/apis/fake_api.py +++ b/samples/client/petstore/python/swagger_client/apis/fake_api.py @@ -112,8 +112,8 @@ class FakeApi(object): raise ValueError("Invalid value for parameter `double` when calling `test_endpoint_parameters`, must be a value less than or equal to `123.4`") if 'double' in params and params['double'] < 67.8: raise ValueError("Invalid value for parameter `double` when calling `test_endpoint_parameters`, must be a value greater than or equal to `67.8`") - if 'string' in params and not re.match('[a-z]+', params['string']): - raise ValueError("Invalid value for parameter `string` when calling `test_endpoint_parameters`, must conform to the pattern `[a-z]+`") + if 'string' in params and not re.search('[a-z]', params['string'], flags=re.IGNORECASE): + raise ValueError("Invalid value for parameter `string` when calling `test_endpoint_parameters`, must conform to the pattern `/[a-z]/i`") if 'integer' in params and params['integer'] > 100.0: raise ValueError("Invalid value for parameter `integer` when calling `test_endpoint_parameters`, must be a value less than or equal to `100.0`") if 'integer' in params and params['integer'] < 10.0: diff --git a/samples/client/petstore/python/swagger_client/models/format_test.py b/samples/client/petstore/python/swagger_client/models/format_test.py index eee1b5c9ef7..7fce3351dd4 100644 --- a/samples/client/petstore/python/swagger_client/models/format_test.py +++ b/samples/client/petstore/python/swagger_client/models/format_test.py @@ -279,7 +279,7 @@ class FormatTest(object): if not string: raise ValueError("Invalid value for `string`, must not be `None`") - if not re.match('/[a-z]/i', string): + if not re.search('[a-z]', string, flags=re.IGNORECASE): raise ValueError("Invalid value for `string`, must be a follow pattern or equal to `/[a-z]/i`") self._string = string