Repository: koxudaxi/datamodel-code-generator

Issue:
Optional command to generate code without constr
**Is your feature request related to a problem? Please describe.**

The inclusion of `constr` in the generated datamodel when it contains regular expressions can cause the generated code to fail checks in mypy and flake8.

Specifically, with `https://github.com/compose-spec/compose-spec/blob/master/schema/compose-spec.json` as the target file, the following command attempts to generate the code.
````
datamodel-codegen --input compose-spec.json --input-file-type jsonschema --output model.py --field-constraints --target-python-version 3.8
````

Part of the generated result contains the following code
```
    services: Optional[Dict[constr(regex=r'^[a-zA-Z0-9._-]+$'), Service]] = None
````
This fails on mypy and flake8 checks.

**Describe the solution you'd like**

The reason for the failure seems to be the use of constr, so I would like an optional command that outputs in a format that does not contain constr (nor conint).

**Describe alternatives you've considered**

If there is already an optional command that accomplishes this kind of functionality, it would be great to know.
I have already tried the `--field-constraints`, `-use-annotated` option commands, etc., but they did not solve this problem.

**Additional context**

If it is difficult to express a constraint by regular expression without using constr, I would like to see a behavior that replaces constr with str and outputs a warning.


Thank you for creating such a great package.

Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/koxudaxi/datamodel-code-generator/pull/726?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono) Report
> Merging [#726](https://codecov.io/gh/koxudaxi/datamodel-code-generator/pull/726?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono) (a4109a2) into [master](https://codecov.io/gh/koxudaxi/datamodel-code-generator/commit/e9b6edfc2e2ace195cb465e2e980fb78c22c3fd9?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono) (e9b6edf) will **decrease** coverage by `0.53%`.
> The diff coverage is `99.31%`.

[![Impacted file tree graph](https://codecov.io/gh/koxudaxi/datamodel-code-generator/pull/726/graphs/tree.svg?width=650&height=150&src=pr&token=plzSSFb9Li&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono)](https://codecov.io/gh/koxudaxi/datamodel-code-generator/pull/726?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono)

```diff
@@             Coverage Diff             @@
##            master     #726      +/-   ##
===========================================
- Coverage   100.00%   99.46%   -0.54%     
===========================================
  Files           11       21      +10     
  Lines         1020     2437    +1417     
  Branches       201      538     +337     
===========================================
+ Hits          1020     2424    +1404     
- Misses           0       13      +13     
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `99.34% <99.15%> (?)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/koxudaxi/datamodel-code-generator/pull/726?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono) | Coverage Δ | |
|---|---|---|
| [datamodel\_code\_generator/model/\_\_init\_\_.py](https://codecov.io/gh/koxudaxi/datamodel-code-generator/pull/726/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono#diff-ZGF0YW1vZGVsX2NvZGVfZ2VuZXJhdG9yL21vZGVsL19faW5pdF9fLnB5) | `100.00% <ø> (ø)` | |
| [datamodel\_code\_generator/\_\_init\_\_.py](https://codecov.io/gh/koxudaxi/datamodel-code-generator/pull/726/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono#diff-ZGF0YW1vZGVsX2NvZGVfZ2VuZXJhdG9yL19faW5pdF9fLnB5) | `91.92% <85.22%> (ø)` | |
| [datamodel\_code\_generator/\_\_main\_\_.py](https://codecov.io/gh/koxudaxi/datamodel-code-generator/pull/726/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono#diff-ZGF0YW1vZGVsX2NvZGVfZ2VuZXJhdG9yL19fbWFpbl9fLnB5) | `100.00% <100.00%> (ø)` | |
| [datamodel\_code\_generator/format.py](https://codecov.io/gh/koxudaxi/datamodel-code-generator/pull/726/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono#diff-ZGF0YW1vZGVsX2NvZGVfZ2VuZXJhdG9yL2Zvcm1hdC5weQ==) | `100.00% <100.00%> (ø)` | |
| [datamodel\_code\_generator/http.py](https://codecov.io/gh/koxudaxi/datamodel-code-generator/pull/726/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono#diff-ZGF0YW1vZGVsX2NvZGVfZ2VuZXJhdG9yL2h0dHAucHk=) | `100.00% <100.00%> (ø)` | |
| [datamodel\_code\_generator/imports.py](https://codecov.io/gh/koxudaxi/datamodel-code-generator/pull/726/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono#diff-ZGF0YW1vZGVsX2NvZGVfZ2VuZXJhdG9yL2ltcG9ydHMucHk=) | `100.00% <100.00%> (ø)` | |
| [datamodel\_code\_generator/model/base.py](https://codecov.io/gh/koxudaxi/datamodel-code-generator/pull/726/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono#diff-ZGF0YW1vZGVsX2NvZGVfZ2VuZXJhdG9yL21vZGVsL2Jhc2UucHk=) | `100.00% <100.00%> (ø)` | |
| [datamodel\_code\_generator/model/enum.py](https://codecov.io/gh/koxudaxi/datamodel-code-generator/pull/726/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono#diff-ZGF0YW1vZGVsX2NvZGVfZ2VuZXJhdG9yL21vZGVsL2VudW0ucHk=) | `100.00% <100.00%> (ø)` | |
| [...atamodel\_code\_generator/model/pydantic/\_\_init\_\_.py](https://codecov.io/gh/koxudaxi/datamodel-code-generator/pull/726/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono#diff-ZGF0YW1vZGVsX2NvZGVfZ2VuZXJhdG9yL21vZGVsL3B5ZGFudGljL19faW5pdF9fLnB5) | `100.00% <100.00%> (ø)` | |
| [...amodel\_code\_generator/model/pydantic/base\_model.py](https://codecov.io/gh/koxudaxi/datamodel-code-generator/pull/726/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono#diff-ZGF0YW1vZGVsX2NvZGVfZ2VuZXJhdG9yL21vZGVsL3B5ZGFudGljL2Jhc2VfbW9kZWwucHk=) | `100.00% <100.00%> (ø)` | |
| ... and [18 more](https://codecov.io/gh/koxudaxi/datamodel-code-generator/pull/726/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/koxudaxi/datamodel-code-generator/pull/726?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/koxudaxi/datamodel-code-generator/pull/726?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono). Last update [ca976e8...a4109a2](https://codecov.io/gh/koxudaxi/datamodel-code-generator/pull/726?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Koudai+Aono).

koxudaxi: @linshoK 
Thank you for creating the PR.
I have added the unittest.
The PR removes validation logic for the dict's key pattern.
We should add the logic as a validator function in the future.


Patch:
diff --git a/datamodel_code_generator/format.py b/datamodel_code_generator/format.py
index 1b2ffb53..a742d884 100644
--- a/datamodel_code_generator/format.py
+++ b/datamodel_code_generator/format.py
@@ -51,7 +51,7 @@ def black_find_project_root(sources: Sequence[Path]) -> Path:
     project_root = _find_project_root(tuple(str(s) for s in sources))
     if isinstance(project_root, tuple):
         return project_root[0]
-    else:
+    else:  # pragma: no cover
         return project_root
 
 
diff --git a/datamodel_code_generator/parser/jsonschema.py b/datamodel_code_generator/parser/jsonschema.py
index 312a786b..5b666378 100644
--- a/datamodel_code_generator/parser/jsonschema.py
+++ b/datamodel_code_generator/parser/jsonschema.py
@@ -670,7 +670,7 @@ class JsonSchemaParser(Parser):
                             is_dict=True,
                             dict_key=self.data_type_manager.get_data_type(
                                 Types.string,
-                                pattern=k,
+                                pattern=k if not self.field_constraints else None,
                             ),
                         )
                         for k, v in item.patternProperties.items()


Test patch:
diff --git a/tests/data/expected/main/main_pattern_properties_field_constraints/output.py b/tests/data/expected/main/main_pattern_properties_field_constraints/output.py
new file mode 100644
index 00000000..446ff3a2
--- /dev/null
+++ b/tests/data/expected/main/main_pattern_properties_field_constraints/output.py
@@ -0,0 +1,17 @@
+# generated by datamodel-codegen:
+#   filename:  pattern_properties.json
+#   timestamp: 2019-07-26T00:00:00+00:00
+
+from __future__ import annotations
+
+from typing import Dict, Optional
+
+from pydantic import BaseModel
+
+
+class Bar(BaseModel):
+    name: Optional[str] = None
+
+
+class Foo(BaseModel):
+    bar: Dict[str, Bar]
diff --git a/tests/test_main.py b/tests/test_main.py
index 8905a357..608a18e6 100644
--- a/tests/test_main.py
+++ b/tests/test_main.py
@@ -3480,6 +3480,34 @@ def test_jsonschema_pattern_properties():
         main()
 
 
+@freeze_time('2019-07-26')
+def test_jsonschema_pattern_properties_field_constraints():
+    with TemporaryDirectory() as output_dir:
+        output_file: Path = Path(output_dir) / 'output.py'
+        return_code: Exit = main(
+            [
+                '--input',
+                str(JSON_SCHEMA_DATA_PATH / 'pattern_properties.json'),
+                '--output',
+                str(output_file),
+                '--input-file-type',
+                'jsonschema',
+                '--field-constraints',
+            ]
+        )
+        assert return_code == Exit.OK
+        assert (
+            output_file.read_text()
+            == (
+                EXPECTED_MAIN_PATH
+                / 'main_pattern_properties_field_constraints'
+                / 'output.py'
+            ).read_text()
+        )
+    with pytest.raises(SystemExit):
+        main()
+
+
 @freeze_time('2019-07-26')
 def test_jsonschema_titles():
     with TemporaryDirectory() as output_dir: