Skip to content

Commit

Permalink
Drop support for platforms where AST nodes aren't weakref-capable
Browse files Browse the repository at this point in the history
  • Loading branch information
malthe committed Jan 9, 2024
1 parent deec3d0 commit 390a1d5
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 58 deletions.
3 changes: 2 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ Changes

In next release ...

-
- Drop support for platforms where AST nodes aren't weakref-capable
(e.g., older PyPy).


4.4.3 (2023-12-30)
Expand Down
11 changes: 0 additions & 11 deletions src/chameleon/astutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

import ast
import collections
import logging
import weakref
from typing import TYPE_CHECKING
from typing import Any
Expand All @@ -40,16 +39,6 @@
node_annotations: MutableMapping[_AnyNode, _AnyNode]
node_annotations = weakref.WeakKeyDictionary()

try:
node_annotations[ast.Name()] = None # type: ignore[assignment]
except TypeError:
logging.debug(
"Unable to create weak references to AST nodes. "
"A lock will be used around compilation loop."
)

node_annotations = {}

__docformat__ = 'restructuredtext en'


Expand Down
79 changes: 33 additions & 46 deletions src/chameleon/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
from chameleon.astutil import TokenRef
from chameleon.astutil import annotated
from chameleon.astutil import load
from chameleon.astutil import node_annotations
from chameleon.astutil import param
from chameleon.astutil import store
from chameleon.astutil import subscript
Expand Down Expand Up @@ -1025,51 +1024,39 @@ def __init__(
strict=strict,
)

if isinstance(node_annotations, dict):
self.lock.acquire()
backup = node_annotations.copy()
else:
backup = None

try:
module = ast.Module([])
module.body += self.visit(node)
ast.fix_missing_locations(module)

class Generator(TemplateCodeGenerator):
scopes = [Scope()]

def visit_EmitText(self, node) -> None:
append = load(self.scopes[-1].append or "__append")
for node in template(
"append(s)", append=append, s=ast.Str(s=node.s)
):
self.visit(node)

def visit_Scope(self, node) -> None:
self.scopes.append(node)
body = list(node.body)
swap(body, load(node.append), "__append")
if node.stream:
swap(body, load(node.stream), "__stream")
for node in body:
self.visit(node)
self.scopes.pop()

generator = Generator(module, source)
tokens = [
Token(source[pos:pos + length], pos, source)
for pos, length in generator.tokens
]
token_map_def = "__tokens = {" + ", ".join("%d: %r" % (
token.pos,
(token, ) + token.location
) for token in tokens) + "}"
finally:
if backup is not None:
node_annotations.clear()
node_annotations.update(backup)
self.lock.release()
module = ast.Module([])
module.body += self.visit(node)
ast.fix_missing_locations(module)

class Generator(TemplateCodeGenerator):
scopes = [Scope()]

def visit_EmitText(self, node) -> None:
append = load(self.scopes[-1].append or "__append")
for node in template(
"append(s)", append=append, s=ast.Str(s=node.s)
):
self.visit(node)

def visit_Scope(self, node) -> None:
self.scopes.append(node)
body = list(node.body)
swap(body, load(node.append), "__append")
if node.stream:
swap(body, load(node.stream), "__stream")
for node in body:
self.visit(node)
self.scopes.pop()

generator = Generator(module, source)
tokens = [
Token(source[pos:pos + length], pos, source)
for pos, length in generator.tokens
]
token_map_def = "__tokens = {" + ", ".join("%d: %r" % (
token.pos,
(token, ) + token.location
) for token in tokens) + "}"

self.code = "\n".join((
"__filename = %r\n" % filename,
Expand Down

0 comments on commit 390a1d5

Please sign in to comment.