Skip to content
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

Loader dumper objects api #563

Draft
wants to merge 2 commits into
base: release/6.0
Choose a base branch
from
Draft

Conversation

ingydotnet
Copy link
Member

@ingydotnet ingydotnet commented Sep 23, 2021

Depends on #561

@@ -76,9 +81,23 @@ def construct_object(self, node, deep=False):
self.recursive_objects[node] = None
constructor = None
tag_suffix = None
if node.tag in self.yaml_constructors:

if (hasattr(self, '_yaml_constructors') and
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would write a wrapper for this. Not sure about a good name.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you plan to add the resolvers and representers in this PR, too?


if (hasattr(self, '_yaml_constructors') and
node.tag in self._yaml_constructors and
self._yaml_constructors[node.tag] is not None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be easier to delete the constructor when doing add_constructor(tag, None)? Then this check wouldn't be necessary


if constructor is None and hasattr(self, '_yaml_constructors'):
for tag_prefix in self._yaml_multi_constructors:
if tag_prefix is not None and node.tag.startswith(tag_prefix):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The None part of the multi_constructors below is not yet supported

Copy link
Member

@perlpunk perlpunk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would be clearer to do something like this at the start of construct_object:

if self.is_instance_based():
    constructors = self._yaml_constructors
    multi_constructors = self._yaml_multi_constructors
else:
    constructors = self.yaml_constructors
    multi_constructors = self.yaml_multi_constructors

Then later code doesn't need to be duplicated

# loader = Loader.get('cls')(stream)

else:
raise AssertionError("Unsupported type for Loader=")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be TypeError.


if loader.stream is None:
if stream is None:
raise AssertionError("load() requires stream=...")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be TypeError.

@perlpunk
Copy link
Member

One thing which is not clear from the example is an important design question:
The current PR looks into the instance based constructors (if it is an instance), and if it doesn't find the tag there, it goes on to search in the class based constructors.
Meaning, doing

l1 = yaml.SafeLoader()
yaml.add_constructor('!dice', dice_constructor, Loader=yaml.SafeLoader)

will still result in finding a constructor for !dice when using l1

My proposal would be to only lookup in one or the other - either instance or class based.
After all we want to get away from the class based global-like thing, and any new stuff would only be supported by the instance API.

@ingydotnet
Copy link
Member Author

One thing which is not clear from the example is an important design question:
The current PR looks into the instance based constructors (if it is an instance), and if it doesn't find the tag there, it goes on to search in the class based constructors.
Meaning, doing

l1 = yaml.SafeLoader()
yaml.add_constructor('!dice', dice_constructor, Loader=yaml.SafeLoader)

will still result in finding a constructor for !dice when using l1

My proposal would be to only lookup in one or the other - either instance or class based.
After all we want to get away from the class based global-like thing, and any new stuff would only be supported by the instance API.

Good point but your instance needs to at least copy over the default class constructors. iow, integers still need to work.

I still have a lot to finish up on this PR. Should have something reviewable by Monday.

lib/yaml/__init__.py Outdated Show resolved Hide resolved
@perlpunk
Copy link
Member

perlpunk commented Sep 25, 2021

Good point but your instance needs to at least copy over the default class constructors.

of course.

iow, integers still need to work.

integers?

instead of just Loader* classes

All existing PyYAML usage should not be affected.
@ingydotnet ingydotnet self-assigned this Jan 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Won't Do
Development

Successfully merging this pull request may close these issues.

None yet

3 participants