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

0.10.1 bug: incorrect "ValueError: Circular reference detected" with multiple empty dictionaries #295

Closed
Edward-Knight opened this issue May 15, 2020 · 6 comments

Comments

@Edward-Knight
Copy link

Edward-Knight commented May 15, 2020

This only affects the latest version (0.10.1) and is fine in previous versions.

Example file that will cause the error (taken from the toml-lang/toml readme):

# [x] you
# [x.y] don't
# [x.y.z] need these
[x.y.z.w] # for this to work

[x] # defining a super-table afterward is ok

The fourth line here ([x.y.z.w]) will cause the new ValueError: Circular reference detected exception in toml.dumps.

Example:

With version 0.10.0:

>>> import toml
>>> toml.dumps({'x': {'y': {'z': {'w': {}}}}})
'[x.y.z.w]\n'
>>> 

With version 0.10.1:

>>> import toml
>>> toml.dumps({'x': {'y': {'z': {'w': {}}}}})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../toml/encoder.py", line 67, in dumps
    raise ValueError("Circular reference detected")
ValueError: Circular reference detected
>>> 
Edward-Knight added a commit to Edward-Knight/toml that referenced this issue May 15, 2020
@andreoliwa
Copy link

I had a similar problem.
I thought it was an issue with OrderedDict and dots (.) on TOML keys.
But the weird thing is: it works for some cases and fails on very specific cases.

Check this gist: toml raises "ValueError: Circular reference detected" on some specific root keys.

For some reason, the id() function is returning the same value for different dict/OrderedDict objects:

toml/toml/encoder.py

Lines 62 to 67 in 9c9d4be

outer_objs = [id(o)]
while sections:
section_ids = [id(section) for section in sections]
for outer_obj in outer_objs:
if outer_obj in section_ids:
raise ValueError("Circular reference detected")

@ottowayi
Copy link

I'm seeing the same issue on Python 3.7 and 3.8. I'm using regulars dicts and just started getting the circular reference error after updating to 0.10.1. I think it has to do with id returning the same value for different objects somehow? What's even weirder is I added some tracking by using a dict of {id(section) : section} then the issue goes away and I can't replicate it the error.

@uiri
Copy link
Owner

uiri commented May 16, 2020

This appears to be a bug in the fix for #217 , which was introduced between 0.10.0 and 0.10.1

My current hypothesis is that the Python runtime creates an empty dictionary, the dictionary gets thrown away and the next time an empty dictionary is "created", the runtime decides to reuse the already created dictionary that was empty and is no longer referenced over allocating a new dictionary.

@Edward-Knight Edward-Knight changed the title Error on dumping tables nested 4+ deep 0.10.1 bug: incorrect "ValueError: Circular reference detected" with multiple empty dictionaries Jun 5, 2020
@misho88
Copy link

misho88 commented Jul 15, 2020

I'm running into the same issue. I've been working around it, but it would be nice to have a fix.

To that end, I would like to suggest using gc.get_referents() instead of trying to use id() which definitely behaves weirdly on {}, [] and others. Garbage collection with reference cycles is why the gc module exists, so it should be safe to assume the implementation of get_referents() is reliable.

Illustrative example:

from gc import get_referents

def has_cycle(obj, visited=()):
    if obj in visited:
        return True
    return any(
        has_cycle(ref, visited + (obj,))
        for ref in get_referents(obj)
    )

d = { '1': { '2': { '3': { '4': {} } } } }
print(d, has_cycle(d))  # {'1': {'2': {'3': {'4': {}}}}} False
try:
    import toml
    toml.dumps(d)
except ValueError as e:
    print('false cycle detected:', e)  # false cycle detected: Circular reference detected
d['1']['2']['3']['4'] = d
print(d, has_cycle(d))  # {'1': {'2': {'3': {'4': {...}}}}} True

@dirkphilip
Copy link
Contributor

I didn't see this issue yet, but I was running into the same problem and created a pull request that
should fix this issue as lijunzh mentioned. For my project, it would also be great if it could be merged and deployed soon.

openstack-mirroring pushed a commit to openstack/requirements that referenced this issue Aug 21, 2020
version 0.10.1 causes a bug with how nested dicts are handled
and we should stay with 0.10.0 until it is fixed:
uiri/toml#295

Change-Id: Id6853599492ad869d25ee8b7f99afa9416926c2b
openstack-mirroring pushed a commit to openstack/openstack that referenced this issue Aug 21, 2020
* Update requirements from branch 'master'
  - cap toml library because of nested dict bug
    
    version 0.10.1 causes a bug with how nested dicts are handled
    and we should stay with 0.10.0 until it is fixed:
    uiri/toml#295
    
    Change-Id: Id6853599492ad869d25ee8b7f99afa9416926c2b
@uiri uiri closed this as completed in 9be6458 Aug 22, 2020
markusressel added a commit to markusressel/container-app-conf that referenced this issue Oct 28, 2020
@kwint
Copy link

kwint commented Oct 28, 2020

Hi @uiri, we encounter this issue quite a bit in our setup, and we are therefore pinned to 0.10.0. But now that other dependencies (like black) are requiring toml 0.10.1 this is starting to hold us back a bit.

Do you have time to make a new release of toml in the near future?

tanaypf9 pushed a commit to tanaypf9/pf9-requirements that referenced this issue May 20, 2024
version 0.10.2 includes a fix for the nested dict bug:
uiri/toml#295  And also happens to be the
latest version currently.

Change-Id: I22014ce24e1480cabe6b02c78a3bf5a23b066973
Signed-off-by: Matthew Thode <mthode@mthode.org>
tanaypf9 pushed a commit to tanaypf9/pf9-requirements that referenced this issue May 20, 2024
version 0.10.2 includes a fix for the nested dict bug:
uiri/toml#295  And also happens to be the
latest version currently.

Change-Id: I22014ce24e1480cabe6b02c78a3bf5a23b066973
tanaypf9 pushed a commit to tanaypf9/pf9-requirements that referenced this issue May 20, 2024
version 0.10.1 causes a bug with how nested dicts are handled
and we should stay with 0.10.0 until it is fixed:
uiri/toml#295

Change-Id: Id6853599492ad869d25ee8b7f99afa9416926c2b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants