Repository: tefra/xsdata

Issue:
Imports raise SyntaxError with FieldName as originalCase
Hi,
I some cases I detected that generated bindings could be invalid when I set in the config FieldName to originalCase.
The generation ends successfully but when I import the module an exception is raised:
```
In [1]: import SampleBindings.my_schema
Traceback (most recent call last):

  File "/home/user/xsdata/lib/python3.9/site-packages/IPython/core/interactiveshell.py", line 3457, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)

  File "<ipython-input-1-c0390bf7dfdc>", line 1, in <module>
    import SampleBindings.my_schema

  File "/home/user/SampleBindings/__init__.py", line 1, in <module>
    from SampleBindings.my_schema import (

  File "/home/user/SampleBindings/my_schema.py", line 12
    @value: Optional[float] = field(
          ^
SyntaxError: invalid syntax
```
If I set in configuration FieldName to pascalCase, the field is correctly generated as "Value".

I prepared a sample package that reproduce problem:
[Sample.tar.gz](https://github.com/tefra/xsdata/files/7939908/Sample.tar.gz)

I tried to change safePrefix value but it doesn't change this behavior.

Thank you for this library

Discussion:
sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; ![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=647&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=647&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=647&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=647&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=647&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=647&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=647&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=647&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=647&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=647&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=647&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=647&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=647) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=647&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=647&metric=new_duplicated_lines_density&view=list)


codecov[bot]: # [Codecov](https://codecov.io/gh/tefra/xsdata/pull/647?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou) Report
> Merging [#647](https://codecov.io/gh/tefra/xsdata/pull/647?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou) (077e077) into [master](https://codecov.io/gh/tefra/xsdata/commit/b8c50fe43fd89791026bee69450eb11146d35883?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou) (b8c50fe) will **not change** coverage.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/tefra/xsdata/pull/647/graphs/tree.svg?width=650&height=150&src=pr&token=YzDDLtywvl&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou)](https://codecov.io/gh/tefra/xsdata/pull/647?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou)

```diff
@@            Coverage Diff            @@
##            master      #647   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           94        94           
  Lines         8214      8212    -2     
  Branches      1584      1583    -1     
=========================================
- Hits          8214      8212    -2     
```


| [Impacted Files](https://codecov.io/gh/tefra/xsdata/pull/647?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou) | Coverage Δ | |
|---|---|---|
| [xsdata/codegen/utils.py](https://codecov.io/gh/tefra/xsdata/pull/647/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou#diff-eHNkYXRhL2NvZGVnZW4vdXRpbHMucHk=) | `100.00% <ø> (ø)` | |
| [xsdata/codegen/handlers/class\_extension.py](https://codecov.io/gh/tefra/xsdata/pull/647/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou#diff-eHNkYXRhL2NvZGVnZW4vaGFuZGxlcnMvY2xhc3NfZXh0ZW5zaW9uLnB5) | `100.00% <100.00%> (ø)` | |
| [xsdata/models/xsd.py](https://codecov.io/gh/tefra/xsdata/pull/647/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou#diff-eHNkYXRhL21vZGVscy94c2QucHk=) | `100.00% <100.00%> (ø)` | |
| [xsdata/utils/constants.py](https://codecov.io/gh/tefra/xsdata/pull/647/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou#diff-eHNkYXRhL3V0aWxzL2NvbnN0YW50cy5weQ==) | `100.00% <100.00%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/tefra/xsdata/pull/647?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou).
> **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=Chris+Tsou)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/tefra/xsdata/pull/647?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou). Last update [b8c50fe...077e077](https://codecov.io/gh/tefra/xsdata/pull/647?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Chris+Tsou). 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=Chris+Tsou).


Patch:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 96c1e206..64e1f316 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -7,7 +7,7 @@ repos:
       - id: pyupgrade
         args: [--py37-plus]
   - repo: https://github.com/asottile/reorder_python_imports
-    rev: v2.6.0
+    rev: v2.7.1
     hooks:
       - id: reorder-python-imports
   - repo: https://github.com/ambv/black
diff --git a/xsdata/codegen/handlers/class_extension.py b/xsdata/codegen/handlers/class_extension.py
index 4b31aaf3..2aa3604d 100644
--- a/xsdata/codegen/handlers/class_extension.py
+++ b/xsdata/codegen/handlers/class_extension.py
@@ -11,6 +11,7 @@ from xsdata.logger import logger
 from xsdata.models.enums import DataType
 from xsdata.models.enums import NamespaceType
 from xsdata.models.enums import Tag
+from xsdata.utils.constants import DEFAULT_ATTR_NAME
 
 
 class ClassExtensionHandler(RelativeHandlerInterface):
@@ -268,7 +269,7 @@ class ClassExtensionHandler(RelativeHandlerInterface):
         type."""
         if extension.type.datatype != DataType.ANY_TYPE:
             tag = Tag.EXTENSION
-            name = "@value"
+            name = DEFAULT_ATTR_NAME
             namespace = None
         else:
             tag = Tag.ANY
diff --git a/xsdata/codegen/utils.py b/xsdata/codegen/utils.py
index 40af0222..4e0331c2 100644
--- a/xsdata/codegen/utils.py
+++ b/xsdata/codegen/utils.py
@@ -136,13 +136,6 @@ class ClassUtils:
             clone = inner.clone()
             clone.package = target.package
             clone.module = target.module
-
-            # Simple type, update the name
-            if clone.name == "@value":
-                namespace, _ = namespaces.split_qname(clone.qname)
-                qname = namespaces.build_qname(namespace, attr.name)
-                clone.qname = attr_type.qname = qname
-
             target.inner.append(clone)
 
     @classmethod
diff --git a/xsdata/models/xsd.py b/xsdata/models/xsd.py
index 5cce1888..fd8a4172 100644
--- a/xsdata/models/xsd.py
+++ b/xsdata/models/xsd.py
@@ -24,14 +24,13 @@ from xsdata.models.mixins import element
 from xsdata.models.mixins import ElementBase
 from xsdata.utils import text
 from xsdata.utils.collections import unique_sequence
+from xsdata.utils.constants import DEFAULT_ATTR_NAME
 from xsdata.utils.namespaces import clean_uri
 
 docstring_serializer = XmlSerializer(
     config=SerializerConfig(pretty_print=True, xml_declaration=False)
 )
 
-DEFAULT_ATTR_NAME = "@value"
-
 
 @dataclass(frozen=True)
 class Docstring:
diff --git a/xsdata/utils/constants.py b/xsdata/utils/constants.py
index 91cf9105..cc6c02b2 100644
--- a/xsdata/utils/constants.py
+++ b/xsdata/utils/constants.py
@@ -10,6 +10,7 @@ EMPTY_TUPLE: Tuple = ()
 
 XML_FALSE = sys.intern("false")
 XML_TRUE = sys.intern("true")
+DEFAULT_ATTR_NAME = "value"
 
 
 def return_true(*_: Any) -> bool:


Test patch:
diff --git a/tests/codegen/handlers/test_class_extension.py b/tests/codegen/handlers/test_class_extension.py
index 28b06f7d..63f22d68 100644
--- a/tests/codegen/handlers/test_class_extension.py
+++ b/tests/codegen/handlers/test_class_extension.py
@@ -444,7 +444,7 @@ class ClassExtensionHandlerTests(FactoryTestCase):
 
         ClassExtensionHandler.add_default_attribute(item, extension)
         expected = AttrFactory.create(
-            name="@value", default=None, types=[xs_string], tag=Tag.EXTENSION
+            name="value", default=None, types=[xs_string], tag=Tag.EXTENSION
         )
 
         self.assertEqual(2, len(item.attrs))
diff --git a/tests/codegen/test_utils.py b/tests/codegen/test_utils.py
index 41bbf24b..05853a5b 100644
--- a/tests/codegen/test_utils.py
+++ b/tests/codegen/test_utils.py
@@ -179,23 +179,6 @@ class ClassUtilsTests(FactoryTestCase):
         self.assertEqual(target.module, target.inner[0].module)
         self.assertEqual(inner.qname, target.inner[0].qname)
 
-    def test_copy_inner_class_rename_simple_inner_type(self):
-        source = ClassFactory.create()
-        inner = ClassFactory.create(qname="{a}@value", module="b", package="c")
-        target = ClassFactory.create()
-        attr = AttrFactory.create(name="simple")
-        attr_type = AttrTypeFactory.create(forward=True, qname=inner.qname)
-
-        source.inner.append(inner)
-        ClassUtils.copy_inner_class(source, target, attr, attr_type)
-
-        self.assertEqual(1, len(target.inner))
-        self.assertIsNot(inner, target.inner[0])
-        self.assertEqual(target.package, target.inner[0].package)
-        self.assertEqual(target.module, target.inner[0].module)
-        self.assertEqual("{a}simple", target.inner[0].qname)
-        self.assertEqual("{a}simple", attr_type.qname)
-
     def test_copy_inner_class_skip_non_forward_reference(self):
         source = ClassFactory.create()
         target = ClassFactory.create()
diff --git a/tests/models/xsd/test_alternative.py b/tests/models/xsd/test_alternative.py
index 27bdb13e..60eb3d2f 100644
--- a/tests/models/xsd/test_alternative.py
+++ b/tests/models/xsd/test_alternative.py
@@ -6,7 +6,7 @@ from xsdata.models.xsd import Alternative
 class AlternativeTests(TestCase):
     def test_property_real_name(self):
         obj = Alternative()
-        self.assertEqual("@value", obj.real_name)
+        self.assertEqual("value", obj.real_name)
 
         obj.id = "foo"
         self.assertEqual("foo", obj.real_name)
diff --git a/tests/models/xsd/test_list.py b/tests/models/xsd/test_list.py
index 4ba9cc0c..23391f1d 100644
--- a/tests/models/xsd/test_list.py
+++ b/tests/models/xsd/test_list.py
@@ -10,7 +10,7 @@ class ListTests(TestCase):
 
     def test_real_name(self):
         obj = List()
-        self.assertEqual("@value", obj.real_name)
+        self.assertEqual("value", obj.real_name)
 
     def test_real_type(self):
         obj = List()
diff --git a/tests/models/xsd/test_restriction.py b/tests/models/xsd/test_restriction.py
index c56f088d..3616c031 100644
--- a/tests/models/xsd/test_restriction.py
+++ b/tests/models/xsd/test_restriction.py
@@ -34,7 +34,7 @@ class RestrictionTests(TestCase):
 
     def test_property_real_name(self):
         obj = Restriction()
-        self.assertEqual("@value", obj.real_name)
+        self.assertEqual("value", obj.real_name)
 
     def test_property_bases(self):
         obj = Restriction()
diff --git a/tests/models/xsd/test_simple_type.py b/tests/models/xsd/test_simple_type.py
index e81007aa..424be2d2 100644
--- a/tests/models/xsd/test_simple_type.py
+++ b/tests/models/xsd/test_simple_type.py
@@ -11,7 +11,7 @@ from xsdata.models.xsd import Union
 class SimpleTypeTests(TestCase):
     def test_property_real_name(self):
         obj = SimpleType()
-        self.assertEqual("@value", obj.real_name)
+        self.assertEqual("value", obj.real_name)
 
         obj.name = "foo"
         self.assertEqual("foo", obj.real_name)
diff --git a/tests/models/xsd/test_union.py b/tests/models/xsd/test_union.py
index 168f9b0a..854058c6 100644
--- a/tests/models/xsd/test_union.py
+++ b/tests/models/xsd/test_union.py
@@ -25,7 +25,7 @@ class UnionTests(TestCase):
 
     def test_property_real_name(self):
         obj = Union()
-        self.assertEqual("@value", obj.real_name)
+        self.assertEqual("value", obj.real_name)
 
     def test_property_attr_types(self):
         obj = Union()