Note: I am aware that this project is no longer being maintained. I'm posting this issue here so that if others experience it, they might be able to work around it as well.
Sly's Lexer class behaves strangely when being dynamically imported, such as through ddtrace-run's _exec_module. This behavior seems to stem from the class Lexer(metaclass=LexerMeta). LexerMeta.__new__ seems to be called on dynamic import, presumably to construct the Lexer class. When LexerMeta.__new__ calls cls._build(), Lexer._build() runs and errors out on this line:
|
part = f'(?P<{tokname}>{pattern})' |
The data collected at the time of error suggests that the contents of value, being evaluated just above the failing line, is currently the re module, which is both not a str and not a callable, so pattern never gets defined, which causes the titular UnboundLocalError.
|
if isinstance(value, str): |
|
pattern = value |
|
|
|
elif callable(value): |
|
cls._token_funcs[tokname] = value |
|
pattern = getattr(value, 'pattern') |
|
|
|
# Form the regular expression component |
|
part = f'(?P<{tokname}>{pattern})' |
Screenshot from sentry showing relevant information:

Workaround
The workaround that we've come up with is to manually from sly import Lexer prior to any of the dynamic importing happening and mark it with a noqa tag to avoid the unused import from getting removed by code quality tools. Manually importing the module first seems to fix the problem.
Possible solution?
I think, if there were to be a fix in Sly, the fix would require determining what to do with pattern when value is neither a str or a callable and then having that as the default behavior. I admit that I do not understand sly very well to understand what implications having a default value here would cause, but it does seem that the lack of an else clause in evaluating the contents of value is the fundamental issue at play here.
Note: I am aware that this project is no longer being maintained. I'm posting this issue here so that if others experience it, they might be able to work around it as well.
Sly's Lexer class behaves strangely when being dynamically imported, such as through
ddtrace-run's_exec_module. This behavior seems to stem from theclass Lexer(metaclass=LexerMeta).LexerMeta.__new__seems to be called on dynamic import, presumably to construct theLexerclass. WhenLexerMeta.__new__callscls._build(),Lexer._build()runs and errors out on this line:sly/src/sly/lex.py
Line 307 in 4000988
The data collected at the time of error suggests that the contents of
value, being evaluated just above the failing line, is currently the re module, which is both not a str and not a callable, sopatternnever gets defined, which causes the titular UnboundLocalError.sly/src/sly/lex.py
Lines 299 to 307 in 4000988
Screenshot from sentry showing relevant information:
Workaround
The workaround that we've come up with is to manually
from sly import Lexerprior to any of the dynamic importing happening and mark it with a noqa tag to avoid the unused import from getting removed by code quality tools. Manually importing the module first seems to fix the problem.Possible solution?
I think, if there were to be a fix in Sly, the fix would require determining what to do with
patternwhenvalueis neither astror acallableand then having that as the default behavior. I admit that I do not understand sly very well to understand what implications having a default value here would cause, but it does seem that the lack of anelseclause in evaluating the contents ofvalueis the fundamental issue at play here.