@@ -433,6 +433,8 @@ def _meta_kwargs_ast(ctx: CompilerContext, # pylint:disable=inconsistent-return
433
433
434
434
_SYM_DYNAMIC_META_KEY = kw .keyword ("dynamic" )
435
435
_SYM_MACRO_META_KEY = kw .keyword ("macro" )
436
+ _SYM_NO_WARN_ON_REDEF_META_KEY = kw .keyword ("no-warn-on-redef" )
437
+ _SYM_REDEF_META_KEY = kw .keyword ("redef" )
436
438
437
439
438
440
def _is_dynamic (v : Var ) -> bool :
@@ -458,6 +460,17 @@ def _is_macro(v: Var) -> bool:
458
460
return False
459
461
460
462
463
+ def _is_redefable (v : Var ) -> bool :
464
+ """Return True if the Var can be redefined."""
465
+ try :
466
+ return Maybe (v .meta ).map (
467
+ lambda m : m .get (_SYM_REDEF_META_KEY , None ) # type: ignore
468
+ ).or_else_get (
469
+ False )
470
+ except (KeyError , AttributeError ):
471
+ return False
472
+
473
+
461
474
def _def_ast (ctx : CompilerContext , form : llist .List ) -> ASTStream :
462
475
"""Return a Python AST Node for a `def` expression."""
463
476
assert form .first == _DEF
@@ -486,8 +499,12 @@ def _def_ast(ctx: CompilerContext, form: llist.List) -> ASTStream:
486
499
yield from meta_nodes
487
500
yield from def_nodes
488
501
489
- if safe_name in ctx .current_ns .module .__dict__ :
490
- logger .warning (f"redefining local Python name '{ safe_name } ' in module '{ ctx .current_ns .module .__name__ } '" )
502
+ if safe_name in ctx .current_ns .module .__dict__ or form [1 ] in ctx .current_ns .interns :
503
+ no_warn_on_redef = (Maybe (form [1 ].meta )
504
+ .map (lambda m : m .get (_SYM_NO_WARN_ON_REDEF_META_KEY , False )) # type: ignore
505
+ .or_else_get (False ))
506
+ if not no_warn_on_redef :
507
+ logger .warning (f"redefining local Python name '{ safe_name } ' in module '{ ctx .current_ns .module .__name__ } '" )
491
508
492
509
yield _dependency (ast .Assign (targets = [ast .Name (id = safe_name , ctx = ast .Store ())],
493
510
value = Maybe (def_value ).map (_unwrap_node ).or_else_get (ast .NameConstant (None ))))
@@ -1487,11 +1504,11 @@ def _kw_ast(_: CompilerContext, form: kw.Keyword) -> ASTStream:
1487
1504
def _resolve_sym_var (ctx : CompilerContext , v : Var ) -> Optional [str ]:
1488
1505
"""Resolve a Basilisp var down to a Python Name (or Attribute).
1489
1506
1490
- If the Var is marked as :dynamic, do not compile to a direct access.
1491
- If the corresponding function name is not defined in a Python module,
1492
- no direct variable access is possible and Var.find indirection must
1493
- be used."""
1494
- if _is_dynamic (v ):
1507
+ If the Var is marked as :dynamic or :redef , do not compile to a direct
1508
+ access. If the corresponding function name is not defined in a Python
1509
+ module, no direct variable access is possible and Var.find indirection
1510
+ must be used."""
1511
+ if _is_dynamic (v ) or _is_redefable ( v ) :
1495
1512
return None
1496
1513
1497
1514
safe_name = munge (v .name .name )
0 commit comments