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

Dumping an object with no attribute crashes #692

Open
lwinkler opened this issue Jan 6, 2023 · 5 comments · May be fixed by #745
Open

Dumping an object with no attribute crashes #692

lwinkler opened this issue Jan 6, 2023 · 5 comments · May be fixed by #745
Assignees
Labels

Comments

@lwinkler
Copy link

lwinkler commented Jan 6, 2023

This is a weird bug with the more recent version of python. Dumping an object that has no attribute raises an error.

It happens with Python 3.11.0 and pyyaml 6.0 on Windows but did not happen for older versions of Python (3.9.13) and pyyaml 6.0

This can be reproduced with:

import yaml

class MyClass(yaml.YAMLObject):
    yaml_loader = yaml.SafeLoader
    yaml_tag = "!MyClass" # Commenting this line fixes the issue


my_object0 = MyClass()
# my_object0.aaa = 1 # Uncommenting this line fixes the issue

print("engine0 is none ?", my_object0 is None, type(my_object0))

print(yaml.dump(my_object0))

Output:

$ python aaa.py 
engine0 is none ? False <class '__main__.MyClass'>
Traceback (most recent call last):
  File "D:\prog\requisite\aaa.py", line 14, in <module>
    print(yaml.dump(my_object0))
          ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\lwink\AppData\Roaming\Python\Python311\site-packages\yaml\__init__.py", line 253, in dump
    return dump_all([data], stream, Dumper=Dumper, **kwds)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\lwink\AppData\Roaming\Python\Python311\site-packages\yaml\__init__.py", line 241, in dump_all
    dumper.represent(data)
  File "C:\Users\lwink\AppData\Roaming\Python\Python311\site-packages\yaml\representer.py", line 27, in represent
    node = self.represent_data(data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\lwink\AppData\Roaming\Python\Python311\site-packages\yaml\representer.py", line 48, in represent_data
    node = self.yaml_representers[data_types[0]](self, data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\lwink\AppData\Roaming\Python\Python311\site-packages\yaml\__init__.py", line 388, in to_yaml
    return dumper.represent_yaml_object(cls.yaml_tag, data, cls,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\lwink\AppData\Roaming\Python\Python311\site-packages\yaml\representer.py", line 228, in represent_yaml_object
    return self.represent_mapping(tag, state, flow_style=flow_style)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\lwink\AppData\Roaming\Python\Python311\site-packages\yaml\representer.py", line 116, in represent_mapping
    for item_key, item_value in mapping:
TypeError: 'NoneType' object is not iterable
@lwinkler
Copy link
Author

This happened with an unstable version of python. It is probably linked to that.

@lwinkler
Copy link
Author

I re-opened the issue because it happens again with python 3.11.4 and PyYAML 6.0.1

import yaml

class MyClass(yaml.YAMLObject):
    yaml_loader = yaml.SafeLoader
    yaml_tag = "!MyClass" # Commenting this line fixes the issue


my_object0 = MyClass()
# my_object0.aaa = 1 # Uncommenting this line fixes the issue

print("my_object is none ?", my_object0 is None, type(my_object0))

print(yaml.dump(my_object0))

gives the error:

my_object is none ? False <class '__main__.MyClass'>
Traceback (most recent call last):
  File "/home/lwinkler/prog/python/modus/ignore/bug_pyyaml.py", line 13, in <module>
    print(yaml.dump(my_object0))
          ^^^^^^^^^^^^^^^^^^^^^
  File "/home/lwinkler/venv/modus/lib/python3.11/site-packages/yaml/__init__.py", line 253, in dump
    return dump_all([data], stream, Dumper=Dumper, **kwds)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/lwinkler/venv/modus/lib/python3.11/site-packages/yaml/__init__.py", line 241, in dump_all
    dumper.represent(data)
  File "/home/lwinkler/venv/modus/lib/python3.11/site-packages/yaml/representer.py", line 27, in represent
    node = self.represent_data(data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/lwinkler/venv/modus/lib/python3.11/site-packages/yaml/representer.py", line 48, in represent_data
    node = self.yaml_representers[data_types[0]](self, data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/lwinkler/venv/modus/lib/python3.11/site-packages/yaml/__init__.py", line 388, in to_yaml
    return dumper.represent_yaml_object(cls.yaml_tag, data, cls,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/lwinkler/venv/modus/lib/python3.11/site-packages/yaml/representer.py", line 228, in represent_yaml_object
    return self.represent_mapping(tag, state, flow_style=flow_style)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/lwinkler/venv/modus/lib/python3.11/site-packages/yaml/representer.py", line 116, in represent_mapping
    for item_key, item_value in mapping:
TypeError: 'NoneType' object is not iterable

@lwinkler
Copy link
Author

It seems that this change python/cpython#70766 causes objects to have a getstate method when none existed before. For an empty object this new getstate method returns None. This causes the serialization to crash.

@nitzmahone
Copy link
Member

@lwinkler thanks for the investigation and link to the underlying issue- that'll save us a lot of time!

@nitzmahone nitzmahone self-assigned this Aug 23, 2023
@lwinkler
Copy link
Author

You are most welcome. Glad to be of any help.

@nitzmahone nitzmahone linked a pull request Aug 23, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants