Move ConfigValueParser into its own module

This enables plugin __init__.py files to import ConfigValue without
app_globals and its dependency on pyx modules.
This commit is contained in:
Max Goodman
2012-06-11 11:23:32 -07:00
parent b90e55a59f
commit 473ee2c9bb
3 changed files with 80 additions and 57 deletions

View File

@@ -30,7 +30,8 @@ mimetypes.init()
import webhelpers
from r2.config import routing
from r2.lib.app_globals import ConfigValue, Globals
from r2.lib.app_globals import Globals
from r2.lib.configparse import ConfigValue
from r2.lib import rpc
import r2.lib.helpers
from r2.lib.plugin import PluginLoader

View File

@@ -28,6 +28,7 @@ from urlparse import urlparse
import json
from sqlalchemy import engine
from sqlalchemy import event
from r2.lib.configparse import ConfigValue, ConfigValueParser
from r2.lib.cache import LocalCache, SelfEmptyingCache
from r2.lib.cache import CMemcache, StaleCacheChain
from r2.lib.cache import HardCache, MemcacheChain, MemcacheChain, HardcacheChain
@@ -39,62 +40,6 @@ from r2.lib.lock import make_lock_factory
from r2.lib.manager import db_manager
from r2.lib.stats import Stats, CacheStats, StatsCollectingConnectionPool
class ConfigValue(object):
@staticmethod
def int(v, key=None, data=None):
return int(v)
@staticmethod
def float(v, key=None, data=None):
return float(v)
@staticmethod
def bool(v, key=None, data=None):
return (v.lower() == 'true') if v else None
@staticmethod
def tuple(v, key=None, data=None):
return tuple(ConfigValue.to_iter(v))
@staticmethod
def choice(v, key, data):
if v not in data:
raise ValueError("Unknown option for %r: %r not in %r" % (key, v, data))
return data[v]
@staticmethod
def to_iter(v, delim = ','):
return (x.strip() for x in v.split(delim) if x)
class ConfigValueParser(dict):
def __init__(self, raw_data):
dict.__init__(self, raw_data)
self.config_keys = {}
self.raw_data = raw_data
def add_spec(self, spec):
new_keys = []
for parser, keys in spec.iteritems():
# keys can be either a list or a dict
for key in keys:
assert key not in self.config_keys
# if keys is a dict, the value is passed as extra data to the parser.
extra_data = keys[key] if type(keys) is dict else None
self.config_keys[key] = (parser, extra_data)
new_keys.append(key)
self._update_values(new_keys)
def _update_values(self, keys):
for key in keys:
if key not in self.raw_data:
continue
value = self.raw_data[key]
if key in self.config_keys:
parser, extra_data = self.config_keys[key]
value = parser(value, key, extra_data)
self[key] = value
class Globals(object):
spec = {

77
r2/r2/lib/configparse.py Normal file
View File

@@ -0,0 +1,77 @@
# The contents of this file are subject to the Common Public Attribution
# License Version 1.0. (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
# License Version 1.1, but Sections 14 and 15 have been added to cover use of
# software over a computer network and provide for limited attribution for the
# Original Developer. In addition, Exhibit A has been modified to be consistent
# with Exhibit B.
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
# the specific language governing rights and limitations under the License.
#
# The Original Code is Reddit.
#
# The Original Developer is the Initial Developer. The Initial Developer of the
# Original Code is CondeNet, Inc.
#
# All portions of the code written by CondeNet are Copyright (c) 2006-2010
# CondeNet, Inc. All Rights Reserved.
################################################################################
class ConfigValue(object):
@staticmethod
def int(v, key=None, data=None):
return int(v)
@staticmethod
def float(v, key=None, data=None):
return float(v)
@staticmethod
def bool(v, key=None, data=None):
return (v.lower() == 'true') if v else None
@staticmethod
def tuple(v, key=None, data=None):
return tuple(ConfigValue.to_iter(v))
@staticmethod
def choice(v, key, data):
if v not in data:
raise ValueError("Unknown option for %r: %r not in %r" % (key, v, data))
return data[v]
@staticmethod
def to_iter(v, delim = ','):
return (x.strip() for x in v.split(delim) if x)
class ConfigValueParser(dict):
def __init__(self, raw_data):
dict.__init__(self, raw_data)
self.config_keys = {}
self.raw_data = raw_data
def add_spec(self, spec):
new_keys = []
for parser, keys in spec.iteritems():
# keys can be either a list or a dict
for key in keys:
assert key not in self.config_keys
# if keys is a dict, the value is passed as extra data to the parser.
extra_data = keys[key] if type(keys) is dict else None
self.config_keys[key] = (parser, extra_data)
new_keys.append(key)
self._update_values(new_keys)
def _update_values(self, keys):
for key in keys:
if key not in self.raw_data:
continue
value = self.raw_data[key]
if key in self.config_keys:
parser, extra_data = self.config_keys[key]
value = parser(value, key, extra_data)
self[key] = value