Repository: joke2k/django-environ
Pull request #36 (2015-08-12 01:24:23)

Add tuple support


Patch:
diff --git a/README.rst b/README.rst
index 0fc900a..89f372e 100644
--- a/README.rst
+++ b/README.rst
@@ -173,6 +173,7 @@ Supported Types
 - float
 - json
 - list (FOO=a,b,c)
+- tuple (FOO=(a,b,c))
 - dict (BAR=key=val,foo=bar)
 - url
 - path (environ.Path)
@@ -217,6 +218,8 @@ Tests
 
 Changelog
 ---------
+=== 0.3.2 (2015-08-11)
+    * Add tuple support
 
 === 0.3.1 (2014-09-03)
   * Add LDAP url support for database (django-ldapdb)
diff --git a/environ/environ.py b/environ/environ.py
index f4d1177..261fd47 100644
--- a/environ/environ.py
+++ b/environ/environ.py
@@ -34,7 +34,7 @@ else:
 
 
 __author__ = 'joke2k'
-__version__ = (0, 3, 1)
+__version__ = (0, 3, 2)
 
 
 # return int if possible
@@ -162,6 +162,12 @@ class Env(object):
         """
         return self.get_value(var, cast=list if not cast else [cast], default=default)
 
+    def tuple(self, var, cast=None, default=NOTSET):
+        """
+        :rtype: tuple
+        """
+        return self.get_value(var, cast=tuple if not cast else (cast,), default=default)
+
     def dict(self, var, cast=dict, default=NOTSET):
         """
         :rtype: dict
@@ -284,6 +290,9 @@ class Env(object):
                 value = value.lower() in cls.BOOLEAN_TRUE_STRINGS
         elif isinstance(cast, list):
             value = list(map(cast[0], [x for x in value.split(',') if x]))
+        elif isinstance(cast, tuple):
+            val = value.strip('(').strip(')').split(',')
+            value = tuple(map(cast[0], [x for x in val if x]))
         elif isinstance(cast, dict):
             key_cast = cast.get('key', str)
             value_cast = cast.get('value', text_type)
@@ -297,6 +306,9 @@ class Env(object):
             value = dict([val.split('=') for val in value.split(',') if val])
         elif cast is list:
             value = [x for x in value.split(',') if x]
+        elif cast is tuple:
+            val = value.strip('(').strip(')').split(',')
+            value = tuple([x for x in val if x])
         elif cast is float:
             # clean string
             float_str = re.sub(r'[^\d,\.]', '', value)


Test patch:
diff --git a/environ/test.py b/environ/test.py
index 9631325..82ad8a4 100644
--- a/environ/test.py
+++ b/environ/test.py
@@ -33,6 +33,7 @@ class BaseTests(unittest.TestCase):
                     BOOL_FALSE_VAR2='False',
                     PROXIED_VAR='$STR_VAR',
                     INT_LIST='42,33',
+                    INT_TUPLE='(42,33)',
                     STR_LIST_WITH_SPACES=' foo,  bar',
                     EMPTY_LIST='',
                     DICT_VAR='foo=bar,test=on',
@@ -105,6 +106,11 @@ class EnvTests(BaseTests):
         self.assertTypeAndValue(list, [42, 33], self.env('INT_LIST', cast=[int]))
         self.assertTypeAndValue(list, [42, 33], self.env.list('INT_LIST', int))
 
+    def test_int_tuple(self):
+        self.assertTypeAndValue(tuple, (42, 33), self.env('INT_LIST', cast=(int,)))
+        self.assertTypeAndValue(tuple, (42, 33), self.env.tuple('INT_LIST', int))
+        self.assertTypeAndValue(tuple, ('42', '33'), self.env.tuple('INT_LIST'))
+
     def test_str_list_with_spaces(self):
         self.assertTypeAndValue(list, [' foo', '  bar'],
                                 self.env('STR_LIST_WITH_SPACES', cast=[text_type]))
@@ -147,7 +153,7 @@ class EnvTests(BaseTests):
         self.assertEqual(mysql_config['USER'], 'bea6eb025ca0d8')
         self.assertEqual(mysql_config['PASSWORD'], '69772142')
         self.assertEqual(mysql_config['PORT'], None)
-        
+
         mysql_gis_config = self.env.db('DATABASE_MYSQL_GIS_URL')
         self.assertEqual(mysql_gis_config['ENGINE'], 'django.contrib.gis.db.backends.mysql')
         self.assertEqual(mysql_gis_config['NAME'], 'some_database')
diff --git a/environ/test_env.txt b/environ/test_env.txt
index eb8e01d..8f5c29b 100644
--- a/environ/test_env.txt
+++ b/environ/test_env.txt
@@ -23,3 +23,4 @@ INT_VAR=42
 STR_LIST_WITH_SPACES= foo,  bar
 STR_VAR=bar
 INT_LIST=42,33
+INT_TUPLE=(42,33)