-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Relationship support #20
base: master
Are you sure you want to change the base?
Relationship support #20
Conversation
d8ed051
to
ed4327c
Compare
modernpython/langPack.py
Outdated
) | ||
# Datatypes based on primitives are never used in the in memory | ||
# representation but only for the schema | ||
or class_details["is_a_float"] == True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@guillaume-alliander <cims:stereotype>CIMDatatype</cims:stereotype>
are never used during the parsing of a cime file, this because they are just metadata.
For example, ApparentPower
is used in datatype of the attribute ACDCConverter.baseS
, which is just a float in the class model.
Options:
- Given that are never used, we remove them as in this code.
- We add to the Fields a metadata called
data_type
(in a similar fashion toin_profile
) so that this metadata is preserved and can be used to extract units and scale factor.
Feelings?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a tad late - I am of 2 minds. I do like the idea of preserving metadata for future use, because at the end of the day we are trying to be generic, but it might be an acute case of YAGNI. I think that if it low effort it's worth keeping it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
generation of data types instances is done, I only need to attach them to the attributes, on tue i should be able to fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@guillaume-alliander also data type annotation is now in
862d7a3
to
de18931
Compare
e25ab16
to
01aa921
Compare
Kudos, SonarCloud Quality Gate passed! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw this PR as ready for review, so I had a look.
A few comments, but the main thing is that right now, no resources files are written when I tried and ran it :)
Also, in PR #21 I split Base.py in a few files, after the comments on pycgmes. There will be rebase needed at some point.
@chicco785 @guillaume-alliander I've merged #16 . Besides, let me know if you would like to play a leading / maintainer role in this project or cimpy. |
@m-mirz i will rebase pr once @guillaume-alliander one is merged. I have already talked with guillame and i will test some additional changes.
Happy to help, with @MarcoPignati (our CTO) we already discussed this. Being a company the work we put may be limited to our needs, but hopefully this is good enough for you :) For cimpy we need to understand your plans, in my understanding currently it's not based on the "modern python" and we won't make much use of it in that case :( Maybe a good idea is to have a call also with @guillaume-alliander and share ideas. My timeline currently is quite bad. What about early January? |
@chicco785 Ok, for the rebase. I will take care of merging. Regarding the roadmap and maintainer role, I am going to talk to Jonas at alliander next week and let you know about the next steps. Thanks for your availability even if it is only limited :-) For cimpy, the one thing that we missed most dearly in python was types. So, we would also support the switch to a modern python version even if that means larger / breaking changes in cimpy. |
@guillaume-alliander Could you please review this PR as well? I have made you maintainer of the project. In case you need more permissions, just let me know. |
95a6ed6
to
4d47385
Compare
rebase completed, not sure about the issue you have that nothing is generated... i am passing these args in vscode:
|
Kudos, SonarCloud Quality Gate passed! |
Kudos, SonarCloud Quality Gate passed! |
053f04f
to
41d41cd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good, but 2 big things I think:
- the alias part in pydantic really worries me. It is I think the root of the 6702 type errors I get in the generated classes :(
- the all resources in one file vs 1 file per resource is something that I think should be optional
@@ -8,4 +8,23 @@ class DataclassConfig: # pylint: disable=too-few-public-methods | |||
|
|||
# By default, with pydantic extra arguments given to a dataclass are silently ignored. | |||
# This matches the default behaviour by failing noisily. | |||
extra = "forbid" | |||
extra = "ignore" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting. Is there a reason to have ignore
instead of forbid
? (and then the comment above needs update :) )
Which makes me wonder if it would be possible to have the user give the config. I think both values can be useful for different use cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ignore
make simpler to create instances out of dictionary generate by other tools, such as SQLAlchemy.
# Type {{dataType}} in CIM # pylint: disable-next=line-too-long | ||
# {{/isAssociationUsed}}{{label}} : {{#setType}}{{dataType}}{{/setType}} = Field({{#setDefault}}{{dataType}}{{/setDefault}}, in_profiles = [{{#attr_origin}}Profile.{{origin}}, {{/attr_origin}}]) {{^isAssociationUsed}}# noqa: E501{{/isAssociationUsed}} | ||
|
||
{{#setNormalizedName}}{{label}}{{/setNormalizedName}} : {{#setType}}{{.}}{{/setType}} = Field({{#setDefault}}{{.}}{{/setDefault}}, in_profiles = [{{#attr_origin}}Profile.{{origin}}, {{/attr_origin}}], {{#setCimDataType}}{{.}}{{/setCimDataType}}alias = "{{label}}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The alias worries me a bit.
Is it needed?
Aliases in pydantic are not exactly what I expect them to be. They have to be used (when accessing an attribute). The initial name basically does not exist any more, which makes the type checkers very confused.
With BaseModel
I am not using them, but if I really need an alias, I create a computed_field
which is a basically property returning the value of the field I want.
With dataclass
, I am not sure how it works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have seen your code comment higher, where I put another comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The alias worries me a bit.
Is it needed?
the issue is that several attributes have the same name of the Dataclass they refer to, and pydantic dislike that. (i can reproduce it an report the error)
Aliases in pydantic are not exactly what I expect them to be. They have to be used (when accessing an attribute). The initial name basically does not exist any more, which makes the type checkers very confused.
https://docs.pydantic.dev/latest/api/config/#pydantic.config.ConfigDict.populate_by_name
allows to create instances using either the attribute name or the alias. not sure if this works also for accessing...
maybe using validation_alias could work instead of alias, leaving serialisation unchanged? I will test
With
BaseModel
I am not using them, but if I really need an alias, I create acomputed_field
which is a basically property returning the value of the field I want.With
dataclass
, I am not sure how it works.
attribute = eval(renderer(text)) | ||
datatype = _compute_data_type(attribute) | ||
field_type = datatype | ||
default = 'default=None' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In a 197 (I grep
'ed :) ) places, we end up with (example from PhaseTapChangerTabular
):
phaseTapChangerTable : PhaseTapChangerTable = Field(default=None, ...)
With default None but no Optional[]
# attributes should never have the same name as a class the may map to | ||
# Python won't be happy with that, so let's normalize attribute names | ||
# and leverage aliasing in pydantic to use the cim attribute capitalization | ||
# during value setting. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am pretty sure this is a pydantic bug: pydantic/pydantic#8240
Aliases would create more issues than it would solve I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hum, not something that can be fixed easily... But I really do not like the alias
way. I'll keep thinking about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, it seems that some python changes are needed: pydantic/pydantic#7327 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we make work 1 resource 1 file with cyclic references, we could use aliases for the imported class names, and this may do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, it seems that some python changes are needed: pydantic/pydantic#7327 (comment)
It might end up being fixed! pydantic/pydantic#8243 (comment) Fingers crossed, here.
output = chevron.render(**args) | ||
file.write(output) | ||
|
||
def run_template_schema(version_path, class_details, templates): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We both have a strong opinion on all resources in one file vs. 1 resource per file.
And both are very valid use cases I believe.
Maybe add an option to decide which one to choose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a strong opinion:) happy to have a look to make work cyclic reference with 1 resource per file, I didn't manage so far.
e0b12b0
to
4f268ef
Compare
Signed-off-by: Federico M. Facca <[email protected]> use enum for <cims:stereotype rdf:resource="http://iec.ch/TC57/NonStandard/UML#enumeration"/> Signed-off-by: Federico M. Facca <[email protected]> don't generate not used classes Signed-off-by: Federico M. Facca <[email protected]> surface cimdatatype and primitive stereoteypes Signed-off-by: Federico M. Facca <[email protected]> normalize attribute names to avoid issues when pointing to classes Signed-off-by: Federico M. Facca <[email protected]> Delete PositionPoint.py Signed-off-by: Federico M. Facca <[email protected]> generate references to classes * clean support for primitives and cim data types * class importer * cyclic reference validator Signed-off-by: Federico M. Facca <[email protected]> copy util.py Signed-off-by: Federico M. Facca <[email protected]> update dataclass config * support populate by name * support deferred evaluation * support build from attributes * change from forbid to ignore (to be tested also without change) Signed-off-by: Federico M. Facca <[email protected]> spring cleans Signed-off-by: Federico M. Facca <[email protected]> attempt to manage cyclic references across multiple files this is not working unfortunately (today); a similar approach may work in the future when superclass inherited type hints may work as well (probably python 3.13+) Signed-off-by: Federico M. Facca <[email protected]>
Signed-off-by: Federico M. Facca <[email protected]>
Signed-off-by: Federico M. Facca <[email protected]>
Co-authored-by: Guillaume Roger <[email protected]> Signed-off-by: Federico M. Facca <[email protected]>
Signed-off-by: Federico M. Facca <[email protected]>
Signed-off-by: Federico M. Facca <[email protected]>
Signed-off-by: Federico M. Facca <[email protected]>
Signed-off-by: Federico M. Facca <[email protected]> annotate datatype Signed-off-by: Federico M. Facca <[email protected]>
Signed-off-by: Federico M. Facca <[email protected]>
Signed-off-by: Federico M. Facca <[email protected]>
5a286a7
to
84f8d10
Compare
Quality Gate passedThe SonarCloud Quality Gate passed, but some issues were introduced. 11 New issues |
hi @guillaume-alliander, how are you? Finally we are at the point of our development roadmap where we are really going to invest on a solution to manage cim. my colleague @HUG0-D is starting to scratch the surface in these days. As first thing today, I am going to check what change during my full immersion on the real time platform, and then let's see what to do with this pr and other potential contributions. |
@m-mirz @guillaume-alliander quite some water under the bridges, let's proceed for simple steps, if you agree:
Then:
|
adding to the loop also devs that seem more active lately: |
This pr takes the journey to bring relationships to modernpython generator based on work covered in zaphiro-technologies#5.
The code is build on top of PR#16, which is required for build reproducibility (using modern library versioning for python).
Tentative plan: