antlr/antlr4 · error · Exception
The object is read only.
Error message
The object is read only.
What it means
ATNDeserializationOptions is a tiny read-only value object: after construction it can be mutated, but the module-level defaultOptions instance is frozen by setting readonly=True. Any attempt to set another attribute on a readonly instance (the custom __setattr__ blocks it) raises this Exception. In practice you hit it by mutating ATNDeserializationOptions.defaultOptions instead of making a copy.
Source
Thrown at runtime/Python3/src/antlr4/atn/ATNDeserializationOptions.py:20
# Use of this file is governed by the BSD 3-clause license that
# can be found in the LICENSE.txt file in the project root.
# need a forward declaration
ATNDeserializationOptions = None
class ATNDeserializationOptions(object):
__slots__ = ('readonly', 'verifyATN', 'generateRuleBypassTransitions')
defaultOptions = None
def __init__(self, copyFrom:ATNDeserializationOptions = None):
self.readonly = False
self.verifyATN = True if copyFrom is None else copyFrom.verifyATN
self.generateRuleBypassTransitions = False if copyFrom is None else copyFrom.generateRuleBypassTransitions
def __setattr__(self, key, value):
if key!="readonly" and self.readonly:
raise Exception("The object is read only.")
super(type(self), self).__setattr__(key,value)
ATNDeserializationOptions.defaultOptions = ATNDeserializationOptions()
ATNDeserializationOptions.defaultOptions.readonly = True
View on GitHub (pinned to 7d5770395b)
Solutions
- Copy first, then mutate, then pass explicitly: opts = ATNDeserializationOptions(ATNDeserializationOptions.defaultOptions); opts.verifyATN = False; ATNDeserializer(opts).deserialize(data).
- Only touch the copy's flags (verifyATN, generateRuleBypassTransitions); never reassign attributes on defaultOptions itself.
Example fix
# before ATNDeserializationOptions.defaultOptions.verifyATN = False # Exception: read only # after from antlr4.atn.ATNDeserializationOptions import ATNDeserializationOptions opts = ATNDeserializationOptions(ATNDeserializationOptions.defaultOptions) opts.verifyATN = False deserializer = ATNDeserializer(opts)
Defensive patterns
Strategy: validation
Validate before calling
def mutable_options(**flags):
opts = ATNDeserializationOptions(ATNDeserializationOptions.defaultOptions)
for k, v in flags.items():
setattr(opts, k, v) # safe: copy is not readonly
return opts Prevention
- Treat defaultOptions as a frozen template; always copy-construct before changing flags
- Never assign to attributes of module-level singletons in this runtime
When it happens
Trigger: ATNDeserializationOptions.defaultOptions.verifyATN = False, or defaultOptions.generateRuleBypassTransitions = True — direct mutation of the frozen singleton.
Common situations: Trying to disable ATN verification or enable rule bypass transitions for the whole process by editing defaultOptions; code copied from the Java runtime where options are cloned.
Related errors
- Invalid state number.
- Could not deserialize ATN with version {} (expected {}).
- IllegalState
- Couldn't identify final state of the precedence rule prefix
- The specified transition type: {} is not valid.
AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14).
Data as JSON: /api/errors/e87aa39723caa217.
Report an issue: GitHub.