Repository: joke2k/django-environ
Pull request #31 (2015-07-12 19:27:03)

adding rfind and find methods to Path
I have added two methods to support `rfind()` and `find()` to provide compatibility for those django applications that depend on settings but are not "Path" aware.

I ran into this issue with [`django-encrypted-fields`](https://github.com/defrex/django-encrypted-fields):
```
File "/home/burhan/work/projects/aubkw/esch/pgw/models.py", line 11, in Gateway
    username = EncryptedCharField(max_length=200)
File "/home/burhan/work/envs/esch-2.7/local/lib/python2.7/site-packages/encrypted_fields/fields.py", line 121, in __init__
    self.keyname = os.path.dirname(self.keydir)
File "/home/burhan/work/envs/esch-2.7/lib/python2.7/posixpath.py", line 122, in dirname
    i = p.rfind('/') + 1
AttributeError: 'Path' object has no attribute 'rfind'
```

burhan: Also did some PEP8 formatting (which is why there are a few whitespace changes).

Patch:
diff --git a/environ/environ.py b/environ/environ.py
index f4d1177..f78ef6d 100644
--- a/environ/environ.py
+++ b/environ/environ.py
@@ -38,17 +38,20 @@ __version__ = (0, 3, 1)
 
 
 # return int if possible
-_cast_int = lambda v: int(v) if isinstance(v, basestring) and v.isdigit() else v
+_cast_int = lambda v: int(v) if isinstance(
+    v, basestring) and v.isdigit() else v
 # return str if possibile
 _cast_str = lambda v: str(v) if isinstance(v, basestring) else v
 
 
 class NoValue(object):
+
     def __repr__(self):
         return '<{0}>'.format(self.__class__.__name__)
 
 
 class Env(object):
+
     """Provide schema-based lookups of environment variables so that each
     caller doesn't have to pass in `cast` and `default` parameters.
 
@@ -110,8 +113,6 @@ class Env(object):
         "simple": "haystack.backends.simple_backend.SimpleEngine",
     }
 
-
-
     def __init__(self, **schema):
         self.schema = schema
 
@@ -180,7 +181,7 @@ class Env(object):
         :rtype: dict
         """
         return self.db_url_config(self.get_value(var, default=default), engine=engine)
-    db=db_url
+    db = db_url
 
     def cache_url(self, var=DEFAULT_CACHE_ENV, default=NOTSET, backend=None):
         """Returns a config dictionary, defaulting to CACHE_URL.
@@ -188,7 +189,7 @@ class Env(object):
         :rtype: dict
         """
         return self.cache_url_config(self.url(var, default=default), backend=backend)
-    cache=cache_url
+    cache = cache_url
 
     def email_url(self, var=DEFAULT_EMAIL_ENV, default=NOTSET, backend=None):
         """Returns a config dictionary, defaulting to EMAIL_URL.
@@ -196,7 +197,7 @@ class Env(object):
         :rtype: dict
         """
         return self.email_url_config(self.url(var, default=default), backend=backend)
-    email=email_url
+    email = email_url
 
     def search_url(self, var=DEFAULT_SEARCH_ENV, default=NOTSET, engine=None):
         """Returns a config dictionary, defaulting to SEARCH_URL.
@@ -222,7 +223,8 @@ class Env(object):
         :returns: Value from environment or default (if set)
         """
 
-        logger.debug("get '{0}' casted as '{1}' with default '{2}'".format(var, cast, default))
+        logger.debug(
+            "get '{0}' casted as '{1}' with default '{2}'".format(var, cast, default))
 
         if var in self.schema:
             var_info = self.schema[var]
@@ -289,18 +291,20 @@ class Env(object):
             value_cast = cast.get('value', text_type)
             value_cast_by_key = cast.get('cast', dict())
             value = dict(map(
-                lambda kv: (key_cast(kv[0]), cls.parse_value(kv[1], value_cast_by_key.get(kv[0], value_cast))),
+                lambda kv: (key_cast(kv[0]), cls.parse_value(
+                    kv[1], value_cast_by_key.get(kv[0], value_cast))),
                 [val.split('=') for val in value.split(';') if val]
             ))
         elif cast is dict:
-        #elif hasattr(cast, '__name__') and cast.__name__ == 'dict':
+            # elif hasattr(cast, '__name__') and cast.__name__ == 'dict':
             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 float:
             # clean string
             float_str = re.sub(r'[^\d,\.]', '', value)
-            # split for avoid thousand separator and different locale comma/dot symbol
+            # split for avoid thousand separator and different locale comma/dot
+            # symbol
             parts = re.split(r'[,\.]', float_str)
             if len(parts) == 1:
                 float_str = parts[0]
@@ -350,7 +354,8 @@ class Env(object):
         if url.scheme == 'sqlite' and path == '':
             path = ':memory:'
         if url.scheme == 'ldap':
-            path = '{scheme}://{hostname}'.format(scheme=_cast_str(url.scheme), hostname=_cast_str(url.hostname))
+            path = '{scheme}://{hostname}'.format(
+                scheme=_cast_str(url.scheme), hostname=_cast_str(url.hostname))
             if url.port:
                 path += ':{port}'.format(port=_cast_str(url.port))
 
@@ -391,7 +396,8 @@ class Env(object):
         :param overrides:
         :return:
         """
-        url = urlparse.urlparse(url) if not isinstance(url, cls.URL_CLASS) else url
+        url = urlparse.urlparse(url) if not isinstance(
+            url, cls.URL_CLASS) else url
 
         location = url.netloc.split(',')
         if len(location) == 1:
@@ -433,7 +439,8 @@ class Env(object):
 
         config = {}
 
-        url = urlparse.urlparse(url) if not isinstance(url, cls.URL_CLASS) else url
+        url = urlparse.urlparse(url) if not isinstance(
+            url, cls.URL_CLASS) else url
 
         # Remove query strings
         path = url.path[1:]
@@ -474,7 +481,8 @@ class Env(object):
     def search_url_config(cls, url, engine=None):
         config = {}
 
-        url = urlparse.urlparse(url) if not isinstance(url, cls.URL_CLASS) else url
+        url = urlparse.urlparse(url) if not isinstance(
+            url, cls.URL_CLASS) else url
 
         # Remove query strings.
         path = url.path[1:]
@@ -498,7 +506,7 @@ class Env(object):
         config.update({
             "URL": urlparse.urlunparse(("http",) + url[1:2] + (path,) + url[3:]),
             "INDEX_NAME": index,
-            })
+        })
 
         if path:
             config.update({
@@ -523,7 +531,8 @@ class Env(object):
         """
         if env_file is None:
             frame = sys._getframe()
-            env_file = os.path.join(os.path.dirname(frame.f_back.f_code.co_filename), '.env')
+            env_file = os.path.join(
+                os.path.dirname(frame.f_back.f_code.co_filename), '.env')
             if not os.path.exists(env_file):
                 warnings.warn("not reading %s - it doesn't exist." % env_file)
                 return
@@ -555,6 +564,7 @@ class Env(object):
 
 
 class Path(object):
+
     """Inspired to Django Two-scoops, handling File Paths in Settings.
 
         >>> from environ import Path
@@ -635,7 +645,8 @@ class Path(object):
             return self.path('../' * other)
         elif isinstance(other, (str, text_type)):
             return Path(self.__root__.rstrip(other))
-        raise TypeError("unsupported operand type(s) for -: '{0}' and '{1}'".format(self, type(other)))
+        raise TypeError(
+            "unsupported operand type(s) for -: '{0}' and '{1}'".format(self, type(other)))
 
     def __invert__(self):
         return self.path('..')
@@ -655,17 +666,28 @@ class Path(object):
     def __unicode__(self):
         return self.__str__()
 
+    def __getitem__(self, *args, **kwargs):
+        return self.__str__().__getitem__(*args, **kwargs)
+
+    def rfind(self, *args, **kwargs):
+        return self.__str__().rfind(*args, **kwargs)
+
+    def find(self, *args, **kwargs):
+        return self.__str__().find(*args, **kwargs)
+
     @staticmethod
     def _absolute_join(base, *paths, **kwargs):
         absolute_path = os.path.abspath(os.path.join(base, *paths))
         if kwargs.get('required', False) and not os.path.exists(absolute_path):
-            raise ImproperlyConfigured("Create required path: {0}".format(absolute_path))
+            raise ImproperlyConfigured(
+                "Create required path: {0}".format(absolute_path))
         return absolute_path
 
+
 def register_scheme(scheme):
     for method in filter(lambda s: s.startswith('uses_'), dir(urlparse)):
         getattr(urlparse, method).append(scheme)
 
 # Register database and cache schemes in URLs.
-for schema in list(Env.DB_SCHEMES.keys()) + list(Env.CACHE_SCHEMES.keys()) + list(Env.SEARCH_SCHEMES.keys()) +list(Env.EMAIL_SCHEMES.keys()):
+for schema in list(Env.DB_SCHEMES.keys()) + list(Env.CACHE_SCHEMES.keys()) + list(Env.SEARCH_SCHEMES.keys()) + list(Env.EMAIL_SCHEMES.keys()):
     register_scheme(schema)


Test patch:
diff --git a/environ/test.py b/environ/test.py
index 9631325..ce5fb1b 100644
--- a/environ/test.py
+++ b/environ/test.py
@@ -78,31 +78,40 @@ class EnvTests(BaseTests):
         self.assertTypeAndValue(int, 42, self.env.int('INT_VAR'))
 
     def test_int_with_none_default(self):
-        self.assertTrue(self.env('NOT_PRESENT_VAR', cast=int, default=None) is None)
+        self.assertTrue(
+            self.env('NOT_PRESENT_VAR', cast=int, default=None) is None)
 
     def test_float(self):
         self.assertTypeAndValue(float, 33.3, self.env('FLOAT_VAR', cast=float))
         self.assertTypeAndValue(float, 33.3, self.env.float('FLOAT_VAR'))
 
-        self.assertTypeAndValue(float, 33.3, self.env('FLOAT_COMMA_VAR', cast=float))
-        self.assertTypeAndValue(float, 123420333.3, self.env('FLOAT_STRANGE_VAR1', cast=float))
-        self.assertTypeAndValue(float, 123420333.3, self.env('FLOAT_STRANGE_VAR2', cast=float))
+        self.assertTypeAndValue(
+            float, 33.3, self.env('FLOAT_COMMA_VAR', cast=float))
+        self.assertTypeAndValue(
+            float, 123420333.3, self.env('FLOAT_STRANGE_VAR1', cast=float))
+        self.assertTypeAndValue(
+            float, 123420333.3, self.env('FLOAT_STRANGE_VAR2', cast=float))
 
     def test_bool_true(self):
-        self.assertTypeAndValue(bool, True, self.env('BOOL_TRUE_VAR', cast=bool))
-        self.assertTypeAndValue(bool, True, self.env('BOOL_TRUE_VAR2', cast=bool))
+        self.assertTypeAndValue(
+            bool, True, self.env('BOOL_TRUE_VAR', cast=bool))
+        self.assertTypeAndValue(
+            bool, True, self.env('BOOL_TRUE_VAR2', cast=bool))
         self.assertTypeAndValue(bool, True, self.env.bool('BOOL_TRUE_VAR'))
 
     def test_bool_false(self):
-        self.assertTypeAndValue(bool, False, self.env('BOOL_FALSE_VAR', cast=bool))
-        self.assertTypeAndValue(bool, False, self.env('BOOL_FALSE_VAR2', cast=bool))
+        self.assertTypeAndValue(
+            bool, False, self.env('BOOL_FALSE_VAR', cast=bool))
+        self.assertTypeAndValue(
+            bool, False, self.env('BOOL_FALSE_VAR2', cast=bool))
         self.assertTypeAndValue(bool, False, self.env.bool('BOOL_FALSE_VAR'))
 
     def test_proxied_value(self):
         self.assertTypeAndValue(text_type, 'bar', self.env('PROXIED_VAR'))
 
     def test_int_list(self):
-        self.assertTypeAndValue(list, [42, 33], self.env('INT_LIST', cast=[int]))
+        self.assertTypeAndValue(
+            list, [42, 33], self.env('INT_LIST', cast=[int]))
         self.assertTypeAndValue(list, [42, 33], self.env.list('INT_LIST', int))
 
     def test_str_list_with_spaces(self):
@@ -120,9 +129,12 @@ class EnvTests(BaseTests):
     def test_dict_parsing(self):
 
         self.assertEqual({'a': '1'}, self.env.parse_value('a=1', dict))
-        self.assertEqual({'a': 1}, self.env.parse_value('a=1', dict(value=int)))
-        self.assertEqual({'a': ['1', '2', '3']}, self.env.parse_value('a=1,2,3', dict(value=[text_type])))
-        self.assertEqual({'a': [1, 2, 3]}, self.env.parse_value('a=1,2,3', dict(value=[int])))
+        self.assertEqual(
+            {'a': 1}, self.env.parse_value('a=1', dict(value=int)))
+        self.assertEqual({'a': ['1', '2', '3']}, self.env.parse_value(
+            'a=1,2,3', dict(value=[text_type])))
+        self.assertEqual(
+            {'a': [1, 2, 3]}, self.env.parse_value('a=1,2,3', dict(value=[int])))
         self.assertEqual({'a': 1, 'b': [1.1, 2.2], 'c': 3},
                          self.env.parse_value('a=1;b=1.1,2.2;c=3', dict(value=int, cast=dict(b=[float]))))
 
@@ -133,9 +145,11 @@ class EnvTests(BaseTests):
 
     def test_db_url_value(self):
         pg_config = self.env.db()
-        self.assertEqual(pg_config['ENGINE'], 'django.db.backends.postgresql_psycopg2')
+        self.assertEqual(
+            pg_config['ENGINE'], 'django.db.backends.postgresql_psycopg2')
         self.assertEqual(pg_config['NAME'], 'd8r82722r2kuvn')
-        self.assertEqual(pg_config['HOST'], 'ec2-107-21-253-135.compute-1.amazonaws.com')
+        self.assertEqual(
+            pg_config['HOST'], 'ec2-107-21-253-135.compute-1.amazonaws.com')
         self.assertEqual(pg_config['USER'], 'uf07k1i6d8ia0v')
         self.assertEqual(pg_config['PASSWORD'], 'wegauwhgeuioweg')
         self.assertEqual(pg_config['PORT'], 5431)
@@ -147,9 +161,10 @@ 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['ENGINE'], 'django.contrib.gis.db.backends.mysql')
         self.assertEqual(mysql_gis_config['NAME'], 'some_database')
         self.assertEqual(mysql_gis_config['HOST'], '127.0.0.1')
         self.assertEqual(mysql_gis_config['USER'], 'user')
@@ -158,16 +173,19 @@ class EnvTests(BaseTests):
 
         sqlite_config = self.env.db('DATABASE_SQLITE_URL')
         self.assertEqual(sqlite_config['ENGINE'], 'django.db.backends.sqlite3')
-        self.assertEqual(sqlite_config['NAME'], '/full/path/to/your/database/file.sqlite')
+        self.assertEqual(
+            sqlite_config['NAME'], '/full/path/to/your/database/file.sqlite')
 
     def test_cache_url_value(self):
 
         cache_config = self.env.cache_url()
-        self.assertEqual(cache_config['BACKEND'], 'django.core.cache.backends.memcached.MemcachedCache')
+        self.assertEqual(
+            cache_config['BACKEND'], 'django.core.cache.backends.memcached.MemcachedCache')
         self.assertEqual(cache_config['LOCATION'], '127.0.0.1:11211')
 
         redis_config = self.env.cache_url('CACHE_REDIS')
-        self.assertEqual(redis_config['BACKEND'], 'redis_cache.cache.RedisCache')
+        self.assertEqual(
+            redis_config['BACKEND'], 'redis_cache.cache.RedisCache')
         self.assertEqual(redis_config['LOCATION'], '127.0.0.1:6379:1')
         self.assertEqual(redis_config['OPTIONS'], {
             'CLIENT_CLASS': 'redis_cache.client.DefaultClient',
@@ -178,14 +196,13 @@ class EnvTests(BaseTests):
 
         email_config = self.env.email_url()
         self.assertEqual(email_config['EMAIL_BACKEND'],
-                'django.core.mail.backends.smtp.EmailBackend')
+                         'django.core.mail.backends.smtp.EmailBackend')
         self.assertEqual(email_config['EMAIL_HOST'], 'smtp.example.com')
         self.assertEqual(email_config['EMAIL_HOST_PASSWORD'], 'password')
         self.assertEqual(email_config['EMAIL_HOST_USER'], 'user@domain.com')
         self.assertEqual(email_config['EMAIL_PORT'], 587)
         self.assertEqual(email_config['EMAIL_USE_TLS'], True)
 
-
     def test_json_value(self):
         self.assertEqual(self.JSON, self.env.json('JSON_VAR'))
 
@@ -201,7 +218,8 @@ class FileEnvTests(EnvTests):
         self._orig_environ = os.environ
         os.environ = {}
         file_path = Path(__file__, is_file=True)('test_env.txt')
-        self.env.read_env(file_path, PATH_VAR=Path(__file__, is_file=True).__root__)
+        self.env.read_env(
+            file_path, PATH_VAR=Path(__file__, is_file=True).__root__)
 
 
 class SchemaEnvTests(BaseTests):
@@ -214,13 +232,15 @@ class SchemaEnvTests(BaseTests):
         self.assertTypeAndValue(float, 33.3, env('NOT_PRESENT_VAR'))
 
         self.assertTypeAndValue(text_type, 'bar', env('STR_VAR'))
-        self.assertTypeAndValue(text_type, 'foo', env('NOT_PRESENT2', default='foo'))
+        self.assertTypeAndValue(
+            text_type, 'foo', env('NOT_PRESENT2', default='foo'))
 
         self.assertTypeAndValue(list, [42, 33], env('INT_LIST'))
         self.assertTypeAndValue(list, [2], env('DEFAULT_LIST'))
 
         # Override schema in this one case
-        self.assertTypeAndValue(text_type, '42', env('INT_VAR', cast=text_type))
+        self.assertTypeAndValue(
+            text_type, '42', env('INT_VAR', cast=text_type))
 
 
 class DatabaseTestSuite(unittest.TestCase):
@@ -229,9 +249,11 @@ class DatabaseTestSuite(unittest.TestCase):
         url = 'postgres://uf07k1i6d8ia0v:wegauwhgeuioweg@ec2-107-21-253-135.compute-1.amazonaws.com:5431/d8r82722r2kuvn'
         url = Env.db_url_config(url)
 
-        self.assertEqual(url['ENGINE'], 'django.db.backends.postgresql_psycopg2')
+        self.assertEqual(
+            url['ENGINE'], 'django.db.backends.postgresql_psycopg2')
         self.assertEqual(url['NAME'], 'd8r82722r2kuvn')
-        self.assertEqual(url['HOST'], 'ec2-107-21-253-135.compute-1.amazonaws.com')
+        self.assertEqual(
+            url['HOST'], 'ec2-107-21-253-135.compute-1.amazonaws.com')
         self.assertEqual(url['USER'], 'uf07k1i6d8ia0v')
         self.assertEqual(url['PASSWORD'], 'wegauwhgeuioweg')
         self.assertEqual(url['PORT'], 5431)
@@ -240,9 +262,11 @@ class DatabaseTestSuite(unittest.TestCase):
         url = 'postgis://uf07k1i6d8ia0v:wegauwhgeuioweg@ec2-107-21-253-135.compute-1.amazonaws.com:5431/d8r82722r2kuvn'
         url = Env.db_url_config(url)
 
-        self.assertEqual(url['ENGINE'], 'django.contrib.gis.db.backends.postgis')
+        self.assertEqual(
+            url['ENGINE'], 'django.contrib.gis.db.backends.postgis')
         self.assertEqual(url['NAME'], 'd8r82722r2kuvn')
-        self.assertEqual(url['HOST'], 'ec2-107-21-253-135.compute-1.amazonaws.com')
+        self.assertEqual(
+            url['HOST'], 'ec2-107-21-253-135.compute-1.amazonaws.com')
         self.assertEqual(url['USER'], 'uf07k1i6d8ia0v')
         self.assertEqual(url['PASSWORD'], 'wegauwhgeuioweg')
         self.assertEqual(url['PORT'], 5431)
@@ -253,7 +277,8 @@ class DatabaseTestSuite(unittest.TestCase):
 
         self.assertEqual(url['ENGINE'], 'django.contrib.gis.db.backends.mysql')
         self.assertEqual(url['NAME'], 'd8r82722r2kuvn')
-        self.assertEqual(url['HOST'], 'ec2-107-21-253-135.compute-1.amazonaws.com')
+        self.assertEqual(
+            url['HOST'], 'ec2-107-21-253-135.compute-1.amazonaws.com')
         self.assertEqual(url['USER'], 'uf07k1i6d8ia0v')
         self.assertEqual(url['PASSWORD'], 'wegauwhgeuioweg')
         self.assertEqual(url['PORT'], 5431)
@@ -305,76 +330,88 @@ class DatabaseTestSuite(unittest.TestCase):
         self.assertEqual(url['USER'], 'cn=admin,dc=nodomain,dc=org')
         self.assertEqual(url['PASSWORD'], 'some_secret_password')
 
+
 class CacheTestSuite(unittest.TestCase):
 
     def test_memcache_parsing(self):
         url = 'memcache://127.0.0.1:11211'
         url = Env.cache_url_config(url)
 
-        self.assertEqual(url['BACKEND'], 'django.core.cache.backends.memcached.MemcachedCache')
+        self.assertEqual(
+            url['BACKEND'], 'django.core.cache.backends.memcached.MemcachedCache')
         self.assertEqual(url['LOCATION'], '127.0.0.1:11211')
 
     def test_memcache_pylib_parsing(self):
         url = 'pymemcache://127.0.0.1:11211'
         url = Env.cache_url_config(url)
 
-        self.assertEqual(url['BACKEND'], 'django.core.cache.backends.memcached.PyLibMCCache')
+        self.assertEqual(
+            url['BACKEND'], 'django.core.cache.backends.memcached.PyLibMCCache')
         self.assertEqual(url['LOCATION'], '127.0.0.1:11211')
 
     def test_memcache_multiple_parsing(self):
         url = 'memcache://172.19.26.240:11211,172.19.26.242:11212'
         url = Env.cache_url_config(url)
 
-        self.assertEqual(url['BACKEND'], 'django.core.cache.backends.memcached.MemcachedCache')
-        self.assertEqual(url['LOCATION'], ['172.19.26.240:11211', '172.19.26.242:11212'])
+        self.assertEqual(
+            url['BACKEND'], 'django.core.cache.backends.memcached.MemcachedCache')
+        self.assertEqual(
+            url['LOCATION'], ['172.19.26.240:11211', '172.19.26.242:11212'])
 
     def test_memcache_socket_parsing(self):
         url = 'memcache:///tmp/memcached.sock'
         url = Env.cache_url_config(url)
 
-        self.assertEqual(url['BACKEND'], 'django.core.cache.backends.memcached.MemcachedCache')
+        self.assertEqual(
+            url['BACKEND'], 'django.core.cache.backends.memcached.MemcachedCache')
         self.assertEqual(url['LOCATION'], 'unix:/tmp/memcached.sock')
 
     def test_dbcache_parsing(self):
         url = 'dbcache://my_cache_table'
         url = Env.cache_url_config(url)
 
-        self.assertEqual(url['BACKEND'], 'django.core.cache.backends.db.DatabaseCache')
+        self.assertEqual(
+            url['BACKEND'], 'django.core.cache.backends.db.DatabaseCache')
         self.assertEqual(url['LOCATION'], 'my_cache_table')
 
     def test_filecache_parsing(self):
         url = 'filecache:///var/tmp/django_cache'
         url = Env.cache_url_config(url)
 
-        self.assertEqual(url['BACKEND'], 'django.core.cache.backends.filebased.FileBasedCache')
+        self.assertEqual(
+            url['BACKEND'], 'django.core.cache.backends.filebased.FileBasedCache')
         self.assertEqual(url['LOCATION'], '/var/tmp/django_cache')
 
     def test_filecache_windows_parsing(self):
         url = 'filecache://C:/foo/bar'
         url = Env.cache_url_config(url)
 
-        self.assertEqual(url['BACKEND'], 'django.core.cache.backends.filebased.FileBasedCache')
+        self.assertEqual(
+            url['BACKEND'], 'django.core.cache.backends.filebased.FileBasedCache')
         self.assertEqual(url['LOCATION'], 'C:/foo/bar')
 
     def test_locmem_parsing(self):
         url = 'locmemcache://'
         url = Env.cache_url_config(url)
 
-        self.assertEqual(url['BACKEND'], 'django.core.cache.backends.locmem.LocMemCache')
+        self.assertEqual(
+            url['BACKEND'], 'django.core.cache.backends.locmem.LocMemCache')
         self.assertEqual(url['LOCATION'], '')
 
     def test_locmem_named_parsing(self):
         url = 'locmemcache://unique-snowflake'
         url = Env.cache_url_config(url)
 
-        self.assertEqual(url['BACKEND'], 'django.core.cache.backends.locmem.LocMemCache')
+        self.assertEqual(
+            url['BACKEND'], 'django.core.cache.backends.locmem.LocMemCache')
         self.assertEqual(url['LOCATION'], 'unique-snowflake')
 
     def test_dummycache_parsing(self):
         url = 'dummycache://'
         url = Env.cache_url_config(url)
 
-        self.assertEqual(url['BACKEND'], 'django.core.cache.backends.dummy.DummyCache')
+        self.assertEqual(
+            url['BACKEND'], 'django.core.cache.backends.dummy.DummyCache')
         self.assertEqual(url['LOCATION'], '')
 
     def test_redis_parsing(self):
@@ -398,7 +435,8 @@ class CacheTestSuite(unittest.TestCase):
         url = 'filecache:///var/tmp/django_cache?timeout=60&max_entries=1000&cull_frequency=0'
         url = Env.cache_url_config(url)
 
-        self.assertEqual(url['BACKEND'], 'django.core.cache.backends.filebased.FileBasedCache')
+        self.assertEqual(
+            url['BACKEND'], 'django.core.cache.backends.filebased.FileBasedCache')
         self.assertEqual(url['LOCATION'], '/var/tmp/django_cache')
         self.assertEqual(url['TIMEOUT'], 60)
         self.assertEqual(url['OPTIONS'], {
@@ -426,7 +464,7 @@ class EmailTests(unittest.TestCase):
         url = Env.email_url_config(url)
 
         self.assertEqual(url['EMAIL_BACKEND'],
-                'django.core.mail.backends.smtp.EmailBackend')
+                         'django.core.mail.backends.smtp.EmailBackend')
         self.assertEqual(url['EMAIL_HOST'], 'smtp.example.com')
         self.assertEqual(url['EMAIL_HOST_PASSWORD'], 'password')
         self.assertEqual(url['EMAIL_HOST_USER'], 'user@domain.com')
@@ -439,7 +477,8 @@ class PathTests(unittest.TestCase):
     def test_path_class(self):
 
         root = Path(__file__, '..', is_file=True)
-        root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../'))
+        root_path = os.path.abspath(
+            os.path.join(os.path.dirname(__file__), '../'))
         self.assertEqual(root(), root_path)
         self.assertEqual(root.__root__, root_path)
 
@@ -449,8 +488,11 @@ class PathTests(unittest.TestCase):
 
     def test_required_path(self):
 
-        self.assertRaises(ImproperlyConfigured, Path, '/not/existing/path/', required=True)
-        self.assertRaises(ImproperlyConfigured, Path(__file__), 'not_existing_path', required=True)
+        self.assertRaises(
+            ImproperlyConfigured, Path, '/not/existing/path/', required=True)
+        self.assertRaises(
+            ImproperlyConfigured, Path(__file__), 'not_existing_path',
+            required=True)
 
     def test_comparison(self):
 
@@ -460,11 +502,21 @@ class PathTests(unittest.TestCase):
         self.assertTrue(Path('/home') == Path('/home'))
         self.assertTrue(Path('/home') != Path('/home/dev'))
 
+        self.assertEqual(Path('/home/foo/').rfind('/'),
+                         str(Path('/home/foo')).rfind('/'))
+
+        self.assertEqual(Path('/home/foo/').find('/home'),
+                         str(Path('/home/foo/')).find('/home'))
+
+        self.assertEqual(Path('/home/foo/')[1],
+                         str(Path('/home/foo/'))[1])
+
         self.assertEqual(~Path('/home'), Path('/'))
         self.assertEqual(Path('/') + 'home', Path('/home'))
-        self.assertEqual(Path('/')+ '/home/public', Path('/home/public'))
+        self.assertEqual(Path('/') + '/home/public', Path('/home/public'))
         self.assertEqual(Path('/home/dev/public') - 2, Path('/home'))
-        self.assertEqual(Path('/home/dev/public') - 'public', Path('/home/dev'))
+        self.assertEqual(
+            Path('/home/dev/public') - 'public', Path('/home/dev'))
 
         self.assertRaises(TypeError, lambda _: Path('/home/dev/') - 'not int')
 
@@ -472,7 +524,8 @@ class PathTests(unittest.TestCase):
 def load_suite():
 
     test_suite = unittest.TestSuite()
-    for case in [EnvTests, FileEnvTests, SchemaEnvTests, PathTests, DatabaseTestSuite, CacheTestSuite, EmailTests]:
+    for case in [EnvTests, FileEnvTests, SchemaEnvTests, PathTests,
+                 DatabaseTestSuite, CacheTestSuite, EmailTests]:
         test_suite.addTest(unittest.makeSuite(case))
     return test_suite