Skip to content

Commit

Permalink
Merge PR #21: Upgrade to Python 3
Browse files Browse the repository at this point in the history
  • Loading branch information
Kissaki authored Jul 16, 2022
2 parents c42113d + 27d0d31 commit 43563cc
Show file tree
Hide file tree
Showing 27 changed files with 1,655 additions and 1,516 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ modules-enabled folder.

## Requirements
mumo requires:
* python 2.7*
* python >=3.2
* python-zeroc-ice
* murmur >=1.2.3*

Expand Down
52 changes: 29 additions & 23 deletions config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# -*- coding: utf-8

# Copyright (C) 2010 Stefan Hacker <[email protected]>
Expand Down Expand Up @@ -29,40 +29,42 @@
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import ConfigParser
import configparser
import types


class Config(object):
"""
Small abstraction for config loading
"""

def __init__(self, filename = None, default = None):
def __init__(self, filename=None, default=None):
if (filename and not default) or \
(not filename and not default): return
sections = set(default.iterkeys())
(not filename and not default): return

sections = set(default.keys())
if filename:
cfg = ConfigParser.RawConfigParser()
cfg = configparser.RawConfigParser()
cfg.optionxform = str
with open(filename) as f:
cfg.readfp(f)
cfg.read_file(f)
sections.update(cfg.sections())

for section in sections:
if type(section) == types.FunctionType: continue

if isinstance(section, types.FunctionType):
continue

match = None
for default_section in default.iterkeys():
for default_section in default.keys():
try:
if section == default_section or \
(type(default_section) == types.FunctionType and default_section(section)):
(isinstance(default_section, types.FunctionType) and default_section(section)):
match = default_section
break
except ValueError:
continue
if match == None:

if match is None:
continue

optiondefaults = default[match]
Expand All @@ -74,7 +76,7 @@ def __init__(self, filename = None, default = None):
else:
try:
self.__dict__[section] = cfg.items(section)
except ConfigParser.NoSectionError:
except configparser.NoSectionError:
self.__dict__[section] = []
else:
self.__dict__[section] = Config()
Expand All @@ -84,42 +86,46 @@ def __init__(self, filename = None, default = None):
else:
try:
self.__dict__[section].__dict__[name] = conv(cfg.get(section, name))
except (ValueError, ConfigParser.NoSectionError, ConfigParser.NoOptionError):
except (ValueError, configparser.NoSectionError, configparser.NoOptionError):
self.__dict__[section].__dict__[name] = vdefault

def __getitem__(self, key):
return self.__dict__.__getitem__(key)

def __contains__(self, key):
return self.__dict__.__contains__(key)


def x2bool(s):
"""
Helper function to convert strings from the config to bool
"""
if isinstance(s, bool):
return s
elif isinstance(s, basestring):
elif isinstance(s, str):
return s.strip().lower() in ['1', 'true']
raise ValueError()


def commaSeperatedIntegers(s):
"""
Helper function to convert a string from the config
containing comma seperated integers into a list of integers
"""
return map(int, s.split(','))
return list(map(int, s.split(',')))


def commaSeperatedStrings(s):
"""
Helper function to convert a string from the config
containing comma seperated strings into a list of strings
"""
return map(str.strip, s.split(','))
return list(map(str.strip, s.split(',')))


def commaSeperatedBool(s):
"""
Helper function to convert a string from the config
containing comma seperated strings into a list of booleans
"""
return map(x2bool, s.split(','))
return list(map(x2bool, s.split(',')))
112 changes: 57 additions & 55 deletions config_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# -*- coding: utf-8

# Copyright (C) 2010 Stefan Hacker <[email protected]>
Expand Down Expand Up @@ -29,25 +29,28 @@
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import unittest
from config import Config, x2bool, commaSeperatedIntegers, commaSeperatedStrings, commaSeperatedBool
from tempfile import mkstemp
import os
import re
import unittest
from tempfile import mkstemp

def create_file(content = None):
from config import Config, x2bool, commaSeperatedIntegers, commaSeperatedStrings, commaSeperatedBool


def create_file(content=None):
"""
Creates a temp file filled with 'content' and returns its path.
The file has to be manually deleted later on
"""
fd, path = mkstemp()
f = os.fdopen(fd, "wb")
if content:
f.write(content)
f.write(content.encode())
f.flush()
f.close()
return path


class ConfigTest(unittest.TestCase):
cfg_content = """[world]
domination = True
Expand All @@ -62,92 +65,91 @@ class ConfigTest(unittest.TestCase):
[Server_2]
value = True
"""
cfg_default = {'world':(('domination', x2bool, False),
('somestr', str, "fail"),
('somenum', int, 0),
('somenumtest', int, 1),
('blubber', str, "empty"),
('serverregex', re.compile, '.*')),
(lambda x: re.match("Server_\d+",x)):(('value', x2bool, True),),
'somethingelse':(('bla', str, "test"),)}

cfg_default = {'world': (('domination', x2bool, False),
('somestr', str, "fail"),
('somenum', int, 0),
('somenumtest', int, 1),
('blubber', str, "empty"),
('serverregex', re.compile, '.*')),
(lambda x: re.match("Server_\d+", x)): (('value', x2bool, True),),
'somethingelse': (('bla', str, "test"),)}

def setUp(self):
pass

def tearDown(self):
pass


def testEmpty(self):
path = create_file()
try:
cfg = Config(path, self.cfg_default)
assert(cfg.world.domination == False)
assert(cfg.world.somestr == "fail")
assert(cfg.world.somenum == 0)
assert (cfg.world.domination == False)
assert (cfg.world.somestr == "fail")
assert (cfg.world.somenum == 0)
self.assertRaises(AttributeError, getattr, cfg.world, "testfallbacknum")
assert(cfg.somethingelse.bla == "test")
assert (cfg.somethingelse.bla == "test")
finally:
os.remove(path)

def testX2bool(self):
assert(x2bool(" true") == True)
assert(x2bool("false") == False)
assert(x2bool(" TrUe") == True)
assert(x2bool("FaLsE ") == False)
assert(x2bool("0 ") == False)
assert(x2bool("1") == True)
assert(x2bool(" 10") == False)
assert(x2bool("notabool") == False)
assert (x2bool(" true") == True)
assert (x2bool("false") == False)
assert (x2bool(" TrUe") == True)
assert (x2bool("FaLsE ") == False)
assert (x2bool("0 ") == False)
assert (x2bool("1") == True)
assert (x2bool(" 10") == False)
assert (x2bool("notabool") == False)

def testCommaSeperatedIntegers(self):
assert(commaSeperatedIntegers(" 1,2 , 333 ") == [1,2,333])
assert (commaSeperatedIntegers(" 1,2 , 333 ") == [1, 2, 333])
self.assertRaises(ValueError, commaSeperatedIntegers, "1,2,a")

def testCommaSeperatedStrings(self):
assert(commaSeperatedStrings("Bernd, the, bred !") == ["Bernd", "the", "bred !"])
assert (commaSeperatedStrings("Bernd, the, bred !") == ["Bernd", "the", "bred !"])

def testCommaSeperatedBool(self):
assert(commaSeperatedBool("tRue ,false, 0, 0, 1,1, test") == [True, False, False, False, True, True, False])
assert (commaSeperatedBool("tRue ,false, 0, 0, 1,1, test") == [True, False, False, False, True, True, False])

def testConfig(self):
path = create_file(self.cfg_content)
try:
try:
cfg = Config(path, self.cfg_default)
except Exception, e:
print e
assert(cfg.world.domination == True)
assert(cfg.world.somestr == "Blabla")
assert(cfg.world.somenum == 10)
except Exception as e:
print(e)
assert (cfg.world.domination == True)
assert (cfg.world.somestr == "Blabla")
assert (cfg.world.somenum == 10)
self.assertRaises(AttributeError, getattr, cfg.world, "testfallbacknum")
self.assertEqual(cfg.world.blubber, "Things %(doesnotexistsasdefault)s")
self.assertEqual(cfg.world.serverregex, re.compile("^\[[\w\d\-\(\):]{1,20}\]$"))
assert(cfg.somethingelse.bla == "test")
assert(cfg.Server_10.value == False)
assert(cfg.Server_2.value == True)
assert(cfg.Server_9.value == True)
assert (cfg.somethingelse.bla == "test")
assert (cfg.Server_10.value == False)
assert (cfg.Server_2.value == True)
assert (cfg.Server_9.value == True)
finally:
os.remove(path)

def testLoadDefault(self):
cfg = Config(default=self.cfg_default)
assert(cfg.world.domination == False)
assert(cfg.somethingelse.bla == "test")
assert(cfg.world.somenum == 0)
assert (cfg.world.domination == False)
assert (cfg.somethingelse.bla == "test")
assert (cfg.world.somenum == 0)

def testGetItem(self):
cfg = Config(default=self.cfg_default)
assert(cfg["world"]["domination"] == False)
assert("world" in cfg)
assert (cfg["world"]["domination"] == False)
assert ("world" in cfg)

def invalidaccess(c):
c["nointhisconfig"]

self.assertRaises(KeyError, invalidaccess, cfg)


if __name__ == "__main__":
#import sys;sys.argv = ['', 'Test.testName']
# import sys;sys.argv = ['', 'Test.testName']
unittest.main()
2 changes: 1 addition & 1 deletion init-script
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ DESC="Mumo bot for Mumble"
WORKDIR=/opt/mumo
PIDDIR=$WORKDIR
PIDFILE=$PIDDIR/mumo.pid
DAEMON=/usr/bin/python
DAEMON=/usr/bin/python3
USER=mumo
GROUP=mumo

Expand Down
2 changes: 1 addition & 1 deletion modules/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# No real module, just here to keep pydev and its
# test runner happy.
# test runner happy.
Loading

0 comments on commit 43563cc

Please sign in to comment.