0

I am migrating scripts from Python2.7 to Python3.6. I have a function that opens a python file and imports the variables. Works fine in 2.7 but in 3.6 I get an error and I can't figure out what the issue is.

Code:

def _load_rules(old_hash=''):
    # Determine if the rules file has changed, and if so reload it
    rules = open(rules_file, 'r').read()
    new_hash = md5(b'rules').hexdigest()
    if new_hash != old_hash:
        exec(rules)
        # C{ignore_rules} and C{notify_rules} come from the script execution
        return (new_hash, ignore_rules, notify_rules)
    return (old_hash, None, None)

This function checks the rules.py file to see if any changes were made and if not it runs exec(rules) which opens the rules.py file and should take in the variables ignore_rules and notify_rules, which are dictionaries of various "rules" for the purposes of these scripts. The rules.py file is formated like so.

import datetime
import re

notify_rules = \
        [{'event': 'failure',
          'access_point': None,
          'expression': re.compile(r'some_regex'),
          'addresses': ['some_email@email.com']},
     {'event': 'failure',
          'access_point': 'access_point_',
          'addresses': ['some_email@email.com']},

ignore_rules = \
        [{'access_point': 'something'},
         {'access_point': 'something'},
         {'access_point': 'something'},
         {'access_point': 'something'},]

Traceback:

File "/app/eam/gaic/ai_mon/monitoring.py", line 174, in _load_rules
            return (new_hash, notify_rules, ignore_rules)
        builtins.NameError: name 'notify_rules' is not defined
iNeedScissors61
  • 191
  • 1
  • 4
  • 16
  • 1
    What's wrong with `from rules import new_hash, notify_rules, ignore_rules`? Or [importing the module dynamically](/questions/301134)? Also, just to make sure, you're aware that Python 2.7 is about as old as windows 7? – Karl Knechtel Apr 13 '23 at 15:10
  • `exec()` supports the pass in of context if you check out the optional params. – JonSG Apr 13 '23 at 15:12
  • @KarlKnechtel I am moving this code OFF of python 2.7 to 3.6... The issue I have is that the exec function in 2.7 worked as intended but in 3.6 it no longer works. It can't import the local variables from the rules.py file. – iNeedScissors61 Apr 13 '23 at 17:01
  • 1
    @iNeedScissors61 so, that code was relying on behavior that was explicitly warned against: modifications to `locals()` being reflected in the local namespace. Instead, explicitly create a namespace: `ns = {}`, then `exec(rules, ns)` then finally, `return (new_hash, ns["ignore_rules"], ns["notify_rules"])` – juanpa.arrivillaga Apr 13 '23 at 17:42
  • @juanpa.arrivillaga I was able to get the errors to stop and code to execute further by editing the line to `exec(rules, globals(), globals())`. I'm curious if that essentially does the same thing? – iNeedScissors61 Apr 13 '23 at 17:51
  • 1
    @iNeedScissors61 **no don't do that**. Don't just *polllute the global namespace*. You should use the explicitly namespace approach I showed you above – juanpa.arrivillaga Apr 13 '23 at 17:52

0 Answers0