3

I have a config file that needs reloading occasionally. The reload is called inside a method of a class that's running within a thread.

I have tried to do this by using globals() but despite the fact print globals() show that they have updated the program does not see the change.

I tried to add global variableName everywhere before using them but still nothing.

After that I considered using __main__ as i know that works but my problem is I cannot set __main__ variables when my variable names are strings read from a file as are the values.

This is my config parser:

def parse_config(path):
  # grab config.ini
  ini_file     = open(root_path + path)
  ini_contents = ini_file.read().replace('\r\n', '\n')
  ini_file.close()
  ini_list     = filter(None, ini_contents.split("\n"))
  ini_settings = [x for x in ini_list if not x.startswith('#')]

  # loop config file lines and set variables
  for line in ini_settings:
    splits = line.split('=', 1)
    name   = splits[0].strip()
    value  = splits[1].strip()

    value = value.replace('THIS/', root_path)
    if value[0] == ':':
      value = value[1:].split(',')
    elif str(value).lower() == 'true':
      value = True
    elif str(value).lower() == 'false':
      value = False

    globals().update({name:value})

Example ini file

# Path to folder where error logs get written
error_log_path    = THIS/logs/

# Print in console (for debugging only)
logg_print        = True

# Log to file
logg_write        = True
logg_file_path    = THIS/logs/

Main app example

class NotifyHandler():

  def __init__(self):
    m = threading.Thread(target=self.process_send)
    m.setDaemon(True)
    m.start()

  def process_send(self):
    while True:
      parse_config('config.ini')
      print logg_print
      time.sleep(10)

NotifyHandler()
while True:
  time.sleep(10)
transilvlad
  • 13,974
  • 13
  • 45
  • 80
  • Can you add an example of the .ini file so I can test your script properly? What output do you see that lets you know globals have updated? Also, you are not closing the .ini file when done, which adds the _\_\__warningregistry\_\__ entry in globals (Py3.4) – noshelter Feb 12 '15 at 15:28
  • I know it changed because I added `print globals()` after calling the function a second time. but after I added print logg_print which is unchanged. Also I have the second call inside a method of a class that's running within a thread. – transilvlad Feb 12 '15 at 15:36
  • Might you need to reload the thread passing an appropriate start value, or have the thread check for an update? I'm not really sure without seeing more of the code (probably even with seeing more of the code). – noshelter Feb 12 '15 at 15:40
  • Thanks for adding the example. I do see the globals update. I think you just need some way to notify the thread. – noshelter Feb 12 '15 at 15:44
  • Ah, I'm on windows, so I don't think I can be much help (not familiar with _pyinotify_). However, hopefully you've got enough info on there someone can swoop down and lend you a hand. – noshelter Feb 12 '15 at 15:51
  • First you really should close the filestream. Second you might want to have a look at [ConfigParser](https://docs.python.org/2/library/configparser.html#module-ConfigParser). Third maybe you should use a global and thread-safe config object rather than setting every parameter as a global variable. – swenzel Feb 12 '15 at 16:08
  • 2
    Forget about thread safe. A plain dictionary is sufficient. Since you only read xor write, you don't need a lock. See [this](http://stackoverflow.com/a/8487936/2677943) comment. – swenzel Feb 12 '15 at 16:15
  • I've run the script and see it updating. Where exactly are you seeing logg_print value not changing? – noshelter Feb 12 '15 at 16:38
  • That's it, using a dictionary as in `__main__.conf`. Thank you. – transilvlad Feb 12 '15 at 16:39
  • @noshelter Perhaps pyinotify does have something to do with it. – transilvlad Feb 12 '15 at 16:39

0 Answers0