nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: netwo-io/apistos
Pull request #151 (2025-03-21 16:13:17)

Feat(service_config): Add configure function to apistos ServiceConfig
Dev associated to issue : https://github.com/netwo-io/apistos/issues/146


Patch:
diff --git a/apistos/src/internal/actix/service_config.rs b/apistos/src/internal/actix/service_config.rs
index 1ee7438..fe87d6b 100644
--- a/apistos/src/internal/actix/service_config.rs
+++ b/apistos/src/internal/actix/service_config.rs
@@ -31,6 +31,15 @@ impl ServiceConfig<'_> {
     self
   }
 
+  /// Wrapper for [`actix_web::web::ServiceConfig::service`](https://docs.rs/actix-web/*/actix_web/web/struct.ServiceConfig.html#method.configure).
+  pub fn configure<F>(&mut self, f: F) -> &mut Self
+  where
+    F: FnOnce(&mut ServiceConfig),
+  {
+    f(self);
+    self
+  }
+
   /// Wrapper for [`actix_web::web::ServiceConfig::service`](https://docs.rs/actix-web/*/actix_web/web/struct.ServiceConfig.html#method.service).
   pub fn service<F>(&mut self, mut factory: F) -> &mut Self
   where


Test patch:
diff --git a/apistos/tests/service_config.rs b/apistos/tests/service_config.rs
new file mode 100644
index 0000000..ee475cd
--- /dev/null
+++ b/apistos/tests/service_config.rs
@@ -0,0 +1,65 @@
+use actix_web::web::{Json, Path};
+use actix_web::{App, Error};
+
+use actix_web::test::{TestRequest, call_service, init_service, try_read_body_json};
+use apistos::app::OpenApiWrapper;
+use apistos::spec::Spec;
+use apistos::web::{ServiceConfig, get};
+use apistos_gen::api_operation;
+use apistos_models::OpenApi;
+
+#[actix_web::test]
+async fn actix_nested_service_config_configure() {
+  #[api_operation(tag = "pet")]
+  pub(crate) async fn test(_params: Path<(u32, String)>) -> Result<Json<()>, Error> {
+    Ok(Json(()))
+  }
+
+  fn cfg_root(cfg: &mut ServiceConfig) {
+    cfg.configure(cfg_sub);
+  }
+
+  fn cfg_sub(cfg: &mut ServiceConfig) {
+    cfg.route("/", get().to(test));
+  }
+
+  let app = App::new()
+    .document(Spec::default())
+    .configure(cfg_root)
+    .build("/openapi.json");
+  let app = init_service(app).await;
+
+  let req = TestRequest::get().uri("/openapi.json").to_request();
+  let resp = call_service(&app, req).await;
+  assert!(resp.status().is_success());
+
+  let body: OpenApi = try_read_body_json(resp).await.expect("Unable to read body");
+  let mut paths: Vec<&String> = body.paths.paths.keys().collect();
+  paths.sort();
+
+  let expected_paths = vec!["/"];
+
+  assert_eq!(paths, expected_paths);
+
+  assert_eq!(body.paths.paths.values().flat_map(|v| v.operations.values()).count(), 1);
+}
+
+// Imports bellow aim at making clippy happy. Those dependencies are necessary for integration-test.
+use actix_service as _;
+use actix_web_lab as _;
+use apistos_core as _;
+use apistos_plugins as _;
+use apistos_rapidoc as _;
+use apistos_redoc as _;
+use apistos_scalar as _;
+use apistos_swagger_ui as _;
+use futures_util as _;
+use garde_actix_web as _;
+use indexmap as _;
+use log as _;
+use md5 as _;
+use once_cell as _;
+use regex as _;
+use schemars as _;
+use serde as _;
+use serde_json as _;
Repository: pointfreeco/swift-case-paths
Pull request #34 (2021-06-25 20:09:55)

Conform CasePath to CustomStringConvertible
Makes things a lil prettier when working with case paths in playgrounds, etc.


Patch:
diff --git a/Sources/CasePaths/CasePath.swift b/Sources/CasePaths/CasePath.swift
index 10cdec2..99fe693 100644
--- a/Sources/CasePaths/CasePath.swift
+++ b/Sources/CasePaths/CasePath.swift
@@ -47,3 +47,9 @@ public struct CasePath<Root, Value> {
     )
   }
 }
+
+extension CasePath: CustomStringConvertible {
+  public var description: String {
+    "CasePath<\(Root.self), \(Value.self)>"
+  }
+}


Test patch:
diff --git a/Tests/CasePathsTests/CasePathsTests.swift b/Tests/CasePathsTests/CasePathsTests.swift
index 6c81a7a..de5cedc 100644
--- a/Tests/CasePathsTests/CasePathsTests.swift
+++ b/Tests/CasePathsTests/CasePathsTests.swift
@@ -323,4 +323,11 @@ final class CasePathsTests: XCTestCase {
       XCTFail()
     }
   }
+
+  func testCustomStringConvertible() {
+    XCTAssertEqual(
+      "\(/Result<String, Error>.success)",
+      "CasePath<Result<String, Error>, String>"
+    )
+  }
 }
Repository: joke2k/django-environ
Pull request #63 (2015-12-25 18:24:20)

add support for smart casting from default type
See #17 



Patch:
diff --git a/environ/environ.py b/environ/environ.py
index 560272f..306b42f 100644
--- a/environ/environ.py
+++ b/environ/environ.py
@@ -301,6 +301,9 @@ class Env(object):
             value = value.lstrip('$')
             value = self.get_value(value, cast=cast, default=default)
 
+        if cast is None and default is not None and not isinstance(default, NoValue):
+            cast = type(default)
+
         if value != default or (parse_default and value):
             value = self.parse_value(value, cast)
 


Test patch:
diff --git a/environ/test.py b/environ/test.py
index c6414b4..6ce240b 100644
--- a/environ/test.py
+++ b/environ/test.py
@@ -269,6 +269,13 @@ class EnvTests(BaseTests):
         root = self.env.path('PATH_VAR')
         self.assertTypeAndValue(Path, Path(self.PATH), root)
 
+    def test_smart_cast(self):
+        self.assertEqual(self.env.get_value('STR_VAR', default='string'), 'bar')
+        self.assertEqual(self.env.get_value('BOOL_TRUE_VAR', default=True), True)
+        self.assertEqual(self.env.get_value('BOOL_FALSE_VAR', default=True), False)
+        self.assertEqual(self.env.get_value('INT_VAR', default=1), 42)
+        self.assertEqual(self.env.get_value('FLOAT_VAR', default=1.2), 33.3)
+
     def test_exported(self):
         self.assertEqual(self.EXPORTED, self.env('EXPORTED_VAR'))
Repository: joke2k/django-environ
Pull request #77 (2016-02-23 20:10:33)

Fix oracle port handling
The Django Oracle drive requires the port argument to be a string (since it calls `.strip()` on it)



Patch:
diff --git a/environ/environ.py b/environ/environ.py
index 6715730..a947cd7 100644
--- a/environ/environ.py
+++ b/environ/environ.py
@@ -388,8 +388,12 @@ class Env(object):
             config['NAME'] = config['HOST']
             config['HOST'] = ''
 
-        if url.scheme == 'oracle' and not config['PORT']:
-            del(config['PORT']) # Django oracle/base.py strips port and fails on None
+        if url.scheme == 'oracle':
+            # Django oracle/base.py strips port and fails on non-string value
+            if not config['PORT']:
+                del(config['PORT'])
+            else:
+                config['PORT'] = str(config['PORT'])
 
         if url.query:
             config_options = {}


Test patch:
diff --git a/environ/test.py b/environ/test.py
index 56841af..3644847 100644
--- a/environ/test.py
+++ b/environ/test.py
@@ -187,7 +187,7 @@ class EnvTests(BaseTests):
         self.assertEqual(oracle_config['HOST'], 'host')
         self.assertEqual(oracle_config['USER'], 'user')
         self.assertEqual(oracle_config['PASSWORD'], 'password')
-        self.assertEqual(oracle_config['PORT'], 1521)
+        self.assertEqual(oracle_config['PORT'], '1521')
 
         sqlite_config = self.env.db('DATABASE_SQLITE_URL')
         self.assertEqual(sqlite_config['ENGINE'], 'django.db.backends.sqlite3')
Repository: joke2k/django-environ
Pull request #129 (2017-06-17 18:20:04)

Add support for environment names with export prefix
Useful if you source the `.env` file directly from bash or equivalent.


Patch:
diff --git a/environ/environ.py b/environ/environ.py
index 24368b3..cab00ad 100644
--- a/environ/environ.py
+++ b/environ/environ.py
@@ -621,7 +621,7 @@ class Env(object):
         logger.debug('Read environment variables from: {0}'.format(env_file))
 
         for line in content.splitlines():
-            m1 = re.match(r'\A([A-Za-z_0-9]+)=(.*)\Z', line)
+            m1 = re.match(r'\A(?:export )?([A-Za-z_0-9]+)=(.*)\Z', line)
             if m1:
                 key, val = m1.group(1), m1.group(2)
                 m2 = re.match(r"\A'(.*)'\Z", val)


Test patch:
diff --git a/environ/test.py b/environ/test.py
index b7f79ba..77d6c30 100644
--- a/environ/test.py
+++ b/environ/test.py
@@ -25,6 +25,7 @@ class BaseTests(unittest.TestCase):
     JSON = dict(one='bar', two=2, three=33.44)
     DICT = dict(foo='bar', test='on')
     PATH = '/home/dev'
+    EXPORTED = 'exported var'
 
     @classmethod
     def generateData(cls):
@@ -56,7 +57,8 @@ class BaseTests(unittest.TestCase):
                     EMAIL_URL=cls.EMAIL,
                     URL_VAR=cls.URL,
                     JSON_VAR=json.dumps(cls.JSON),
-                    PATH_VAR=cls.PATH)
+                    PATH_VAR=cls.PATH,
+                    EXPORTED_VAR=cls.EXPORTED)
 
     def setUp(self):
         self._old_environ = os.environ
@@ -241,6 +243,9 @@ class EnvTests(BaseTests):
         root = self.env.path('PATH_VAR')
         self.assertTypeAndValue(Path, Path(self.PATH), root)
 
+    def test_exported(self):
+        self.assertEqual(self.EXPORTED, self.env('EXPORTED_VAR'))
+
 
 class FileEnvTests(EnvTests):
 
diff --git a/environ/test_env.txt b/environ/test_env.txt
index e33078b..c0112c3 100644
--- a/environ/test_env.txt
+++ b/environ/test_env.txt
@@ -28,3 +28,4 @@ INT_TUPLE=(42,33)
 DATABASE_ORACLE_TNS_URL=oracle://user:password@sid
 DATABASE_ORACLE_URL=oracle://user:password@host:1521/sid
 DATABASE_REDSHIFT_URL=redshift://user:password@examplecluster.abc123xyz789.us-west-2.redshift.amazonaws.com:5439/dev
+export EXPORTED_VAR="exported var"
\ No newline at end of file
Repository: joke2k/django-environ
Pull request #140 (2017-07-17 00:13:07)

Add __contains__
Allows using `"VARNAME" in env` syntax, which is useful to enable special behavior if a variable is not defined, without worrying about the type of the variable.

Currently, this ignores the schema, which seems more intuitive to me (ie. true means it's explicitly defined somewhere). 


Patch:
diff --git a/environ/environ.py b/environ/environ.py
index 24368b3..db9efa0 100644
--- a/environ/environ.py
+++ b/environ/environ.py
@@ -126,6 +126,9 @@ class Env(object):
     def __call__(self, var, cast=None, default=NOTSET, parse_default=False):
         return self.get_value(var, cast=cast, default=default, parse_default=parse_default)
 
+    def __contains__(self, var):
+        return var in self.ENVIRON
+
     # Shortcuts
 
     def str(self, var, default=NOTSET):


Test patch:
diff --git a/environ/test.py b/environ/test.py
index b7f79ba..fe63cad 100644
--- a/environ/test.py
+++ b/environ/test.py
@@ -79,6 +79,11 @@ class EnvTests(BaseTests):
     def test_not_present_without_default(self):
         self.assertRaises(ImproperlyConfigured, self.env, 'not_present')
 
+    def test_contains(self):
+        self.assertTrue('STR_VAR' in self.env)
+        self.assertTrue('EMPTY_LIST' in self.env)
+        self.assertFalse('I_AM_NOT_A_VAR' in self.env)
+
     def test_str(self):
         self.assertTypeAndValue(str, 'bar', self.env('STR_VAR'))
         self.assertTypeAndValue(str, 'bar', self.env.str('STR_VAR'))
Repository: joke2k/django-environ
Pull request #158 (2017-12-08 16:22:11)

Support PostgreSQL unix domain socket paths
Support PostgreSQL URL using unix domain socket paths, e.g. `postgres:////var/run/postgresql/db`



Patch:
diff --git a/environ/environ.py b/environ/environ.py
index 1365a29..efca36d 100644
--- a/environ/environ.py
+++ b/environ/environ.py
@@ -393,6 +393,9 @@ class Env(object):
             'PORT': _cast_int(url.port) or '',
         })
 
+        if url.scheme == 'postgres' and path.startswith('/'):
+            config['HOST'], config['NAME'] = path.rsplit('/', 1)
+
         if url.scheme == 'oracle' and path == '':
             config['NAME'] = config['HOST']
             config['HOST'] = ''


Test patch:
diff --git a/environ/test.py b/environ/test.py
index 78a373f..d3f9377 100644
--- a/environ/test.py
+++ b/environ/test.py
@@ -301,6 +301,14 @@ class DatabaseTestSuite(unittest.TestCase):
         self.assertEqual(url['PASSWORD'], 'wegauwhgeuioweg')
         self.assertEqual(url['PORT'], 5431)
 
+    def test_postgres_parsing_unix_domain_socket(self):
+        url = 'postgres:////var/run/postgresql/db'
+        url = Env.db_url_config(url)
+
+        self.assertEqual(url['ENGINE'], 'django.db.backends.postgresql_psycopg2')
+        self.assertEqual(url['NAME'], 'db')
+        self.assertEqual(url['HOST'], '/var/run/postgresql')
+
     def test_postgis_parsing(self):
         url = 'postgis://uf07k1i6d8ia0v:wegauwhgeuioweg@ec2-107-21-253-135.compute-1.amazonaws.com:5431/d8r82722r2kuvn'
         url = Env.db_url_config(url)
@@ -496,7 +504,7 @@ class CacheTestSuite(unittest.TestCase):
         self.assertEqual(url['OPTIONS'], {
             'DB': 0
         })
-    
+
     def test_options_parsing(self):
         url = 'filecache:///var/tmp/django_cache?timeout=60&max_entries=1000&cull_frequency=0'
         url = Env.cache_url_config(url)
Repository: joke2k/django-environ
Pull request #177 (2018-03-05 20:22:59)

Make `environ.Path` a `PathLike` object
Adding the `__fspath__` method makes the std lib of Python 3.6 recognize `Path` objects as '[PathLike](https://docs.python.org/3/library/os.html#os.PathLike)'. This way, `Path` objects can be used with functions from `os.path`, such as `makedirs`

coveralls: 
[![Coverage Status](https://coveralls.io/builds/15816816/badge)](https://coveralls.io/builds/15816816)

Coverage decreased (-0.2%) to 88.235% when pulling **2714457ef1c7eb28ddb878ecef7e6a0898375d52 on fcurella:fcurella-patch-1** into **628ed38e540ec9a6f3aff622953948e54f14a76d on joke2k:develop**.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/15816816/badge)](https://coveralls.io/builds/15816816)

Coverage decreased (-0.2%) to 88.235% when pulling **2714457ef1c7eb28ddb878ecef7e6a0898375d52 on fcurella:fcurella-patch-1** into **628ed38e540ec9a6f3aff622953948e54f14a76d on joke2k:develop**.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/15816816/badge)](https://coveralls.io/builds/15816816)

Coverage decreased (-0.2%) to 88.235% when pulling **2714457ef1c7eb28ddb878ecef7e6a0898375d52 on fcurella:fcurella-patch-1** into **628ed38e540ec9a6f3aff622953948e54f14a76d on joke2k:develop**.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/15816816/badge)](https://coveralls.io/builds/15816816)

Coverage decreased (-0.2%) to 88.235% when pulling **2714457ef1c7eb28ddb878ecef7e6a0898375d52 on fcurella:fcurella-patch-1** into **628ed38e540ec9a6f3aff622953948e54f14a76d on joke2k:develop**.


Patch:
diff --git a/environ/environ.py b/environ/environ.py
index 1365a29..8fc8105 100644
--- a/environ/environ.py
+++ b/environ/environ.py
@@ -753,6 +753,9 @@ class Path(object):
 
     def __getitem__(self, *args, **kwargs):
         return self.__str__().__getitem__(*args, **kwargs)
+    
+    def __fspath__(self):
+        return self.__str__()
 
     def rfind(self, *args, **kwargs):
         return self.__str__().rfind(*args, **kwargs)


Test patch:
diff --git a/environ/test.py b/environ/test.py
index 78a373f..7b4d6e9 100644
--- a/environ/test.py
+++ b/environ/test.py
@@ -665,6 +665,7 @@ class PathTests(unittest.TestCase):
         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/foo/').__fspath__(), str(Path('/home/foo/')))
 
         self.assertEqual(~Path('/home'), Path('/'))
         self.assertEqual(Path('/') + 'home', Path('/home'))
Repository: joke2k/django-environ
Pull request #184 (2018-05-16 11:28:38)

Multiline support for strings
Based on https://github.com/nickstenning/honcho/pull/129


Patch:
diff --git a/environ/environ.py b/environ/environ.py
index 1365a29..9dbf60f 100644
--- a/environ/environ.py
+++ b/environ/environ.py
@@ -134,11 +134,14 @@ class Env(object):
 
     # Shortcuts
 
-    def str(self, var, default=NOTSET):
+    def str(self, var, default=NOTSET, multiline=False):
         """
         :rtype: str
         """
-        return self.get_value(var, default=default)
+        value = self.get_value(var, default=default)
+        if multiline:
+            return value.replace('\\n', '\n')
+        return value
 
     def unicode(self, var, default=NOTSET):
         """Helper for python2


Test patch:
diff --git a/environ/test.py b/environ/test.py
index 78a373f..9b0afca 100644
--- a/environ/test.py
+++ b/environ/test.py
@@ -29,6 +29,7 @@ class BaseTests(unittest.TestCase):
     @classmethod
     def generateData(cls):
         return dict(STR_VAR='bar',
+                    MULTILINE_STR_VAR='foo\\nbar',
                     INT_VAR='42',
                     FLOAT_VAR='33.3',
                     FLOAT_COMMA_VAR='33,3',
@@ -87,6 +88,8 @@ class EnvTests(BaseTests):
     def test_str(self):
         self.assertTypeAndValue(str, 'bar', self.env('STR_VAR'))
         self.assertTypeAndValue(str, 'bar', self.env.str('STR_VAR'))
+        self.assertTypeAndValue(str, 'foo\\nbar', self.env.str('MULTILINE_STR_VAR'))
+        self.assertTypeAndValue(str, 'foo\nbar', self.env.str('MULTILINE_STR_VAR', multiline=True))
 
     def test_int(self):
         self.assertTypeAndValue(int, 42, self.env('INT_VAR', cast=int))
diff --git a/environ/test_env.txt b/environ/test_env.txt
index e33078b..23db825 100644
--- a/environ/test_env.txt
+++ b/environ/test_env.txt
@@ -22,6 +22,7 @@ EMPTY_LIST=
 INT_VAR=42
 STR_LIST_WITH_SPACES= foo,  bar
 STR_VAR=bar
+MULTILINE_STR_VAR=foo\nbar
 INT_LIST=42,33
 CYRILLIC_VAR=фуубар
 INT_TUPLE=(42,33)
Repository: joke2k/django-environ
Pull request #235 (2019-10-11 10:56:00)

Validate empty cache url and unknown cache scheme
Signed-off-by: Chenxiong Qi <qcxhome@gmail.com>

coveralls: 
[![Coverage Status](https://coveralls.io/builds/26256247/badge)](https://coveralls.io/builds/26256247)

Coverage increased (+3.04%) to 88.756% when pulling **bba7affd322565c2bd2be0b1a92e0128ce5a8459 on tkdchen:validate-cache-url** into **c2620021614557abe197578f99deeef42af3e082 on joke2k:develop**.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/26256247/badge)](https://coveralls.io/builds/26256247)

Coverage increased (+3.04%) to 88.756% when pulling **bba7affd322565c2bd2be0b1a92e0128ce5a8459 on tkdchen:validate-cache-url** into **c2620021614557abe197578f99deeef42af3e082 on joke2k:develop**.


Patch:
diff --git a/environ/environ.py b/environ/environ.py
index ea4978c..0c6c635 100644
--- a/environ/environ.py
+++ b/environ/environ.py
@@ -447,7 +447,14 @@ class Env(object):
         :param backend:
         :return:
         """
-        url = urlparse(url) if not isinstance(url, cls.URL_CLASS) else url
+        if not isinstance(url, cls.URL_CLASS):
+            if not url:
+                return {}
+            else:
+                url = urlparse(url)
+
+        if url.scheme not in cls.CACHE_SCHEMES:
+            raise ImproperlyConfigured('Invalid cache schema {}'.format(url.scheme))
 
         location = url.netloc.split(',')
         if len(location) == 1:


Test patch:
diff --git a/environ/test.py b/environ/test.py
index 2325816..21eb771 100644
--- a/environ/test.py
+++ b/environ/test.py
@@ -587,6 +587,17 @@ class CacheTestSuite(unittest.TestCase):
             'BARS': 9001,
         })
 
+    def test_unknown_backend(self):
+        url = 'unknown-scheme://127.0.0.1:1000'
+        with self.assertRaises(ImproperlyConfigured) as cm:
+            Env.cache_url_config(url)
+        self.assertEqual(str(cm.exception),
+                         'Invalid cache schema unknown-scheme')
+
+    def test_empty_url_is_mapped_to_empty_config(self):
+        self.assertEqual(Env.cache_url_config(''), {})
+        self.assertEqual(Env.cache_url_config(None), {})
+
 
 class SearchTestSuite(unittest.TestCase):
Repository: joke2k/django-environ
Pull request #400 (2022-06-19 13:22:31)

Value of dict can now contain an equal sign


Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 45d44e0..a36598b 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -11,6 +11,8 @@ Added
 +++++
 - Use the core redis library by default if running Django >= 4.0
   `#356 <https://github.com/joke2k/django-environ/issues/356>`_.
+- Value of dict can now contain an equal sign
+  `#241 <https://github.com/joke2k/django-environ/pull/241>`_.
 
 Deprecated
 ++++++++++
diff --git a/environ/environ.py b/environ/environ.py
index 0ca2575..7731136 100644
--- a/environ/environ.py
+++ b/environ/environ.py
@@ -453,7 +453,7 @@ class Env:
                 [val.split('=') for val in value.split(';') if val]
             ))
         elif cast is dict:
-            value = dict([val.split('=') for val in value.split(',') if val])
+            value = dict([v.split('=', 1) for v in value.split(',') if v])
         elif cast is list:
             value = [x for x in value.split(',') if x]
         elif cast is tuple:


Test patch:
diff --git a/tests/fixtures.py b/tests/fixtures.py
index c7f8a0b..6990d9a 100644
--- a/tests/fixtures.py
+++ b/tests/fixtures.py
@@ -25,6 +25,7 @@ class FakeEnv:
     EMAIL = 'smtps://user@domain.com:password@smtp.example.com:587'
     JSON = dict(one='bar', two=2, three=33.44)
     DICT = dict(foo='bar', test='on')
+    DICT_WITH_EQ = dict(key1='sub_key1=sub_value1', key2='value2')
     PATH = '/home/dev'
     EXPORTED = 'exported var'
     SAML_ATTRIBUTE_MAPPING = dict(
@@ -67,6 +68,7 @@ class FakeEnv:
                     STR_LIST_WITH_SPACES=' foo,  bar',
                     EMPTY_LIST='',
                     DICT_VAR='foo=bar,test=on',
+                    DICT_WITH_EQ_VAR='key1=sub_key1=sub_value1,key2=value2',
                     DATABASE_URL=cls.POSTGRES,
                     DATABASE_MYSQL_URL=cls.MYSQL,
                     DATABASE_MYSQL_GIS_URL=cls.MYSQLGIS,
diff --git a/tests/test_env.py b/tests/test_env.py
index 32aeb20..4df0a27 100644
--- a/tests/test_env.py
+++ b/tests/test_env.py
@@ -185,6 +185,7 @@ class TestEnv:
 
     def test_dict_value(self):
         assert_type_and_value(dict, FakeEnv.DICT, self.env.dict('DICT_VAR'))
+        assert_type_and_value(dict, FakeEnv.DICT_WITH_EQ, self.env.dict('DICT_WITH_EQ_VAR'))
 
     def test_complex_dict_value(self):
         assert_type_and_value(
diff --git a/tests/test_env.txt b/tests/test_env.txt
index 69dc84e..237489b 100644
--- a/tests/test_env.txt
+++ b/tests/test_env.txt
@@ -1,4 +1,5 @@
 DICT_VAR=foo=bar,test=on
+DICT_WITH_EQ_VAR=key1=sub_key1=sub_value1,key2=value2
 
 # Database variables
 DATABASE_MYSQL_URL=mysql://bea6eb0:69772142@us-cdbr-east.cleardb.com/heroku_97681?reconnect=true
Repository: joke2k/django-environ
Pull request #405 (2022-06-29 22:00:08)

Skip parsing only when `default=None`, not for all default values that coerce to `False`
Fixes joke2k/django-environ#404


Patch:
diff --git a/environ/environ.py b/environ/environ.py
index 52f59a6..41b063f 100644
--- a/environ/environ.py
+++ b/environ/environ.py
@@ -409,7 +409,7 @@ class Env:
 
         value = None if default is None and value == '' else value
 
-        if value != default or (parse_default and value):
+        if value != default or (parse_default and value is not None):
             value = self.parse_value(value, cast)
 
         return value


Test patch:
diff --git a/tests/test_env.py b/tests/test_env.py
index 4df0a27..396c212 100644
--- a/tests/test_env.py
+++ b/tests/test_env.py
@@ -227,6 +227,13 @@ class TestEnv:
         assert url.geturl() == FakeEnv.URL
         assert self.env.url('OTHER_URL', default=None) is None
 
+    def test_url_empty_string_default_value(self):
+        unset_var_name = 'VARIABLE_NOT_SET_IN_ENVIRONMENT'
+        assert unset_var_name not in os.environ
+        url = self.env.url(unset_var_name, '')
+        assert url.__class__ == self.env.URL_CLASS
+        assert url.geturl() == ''
+
     def test_url_encoded_parts(self):
         password_with_unquoted_characters = "#password"
         encoded_url = "mysql://user:%s@127.0.0.1:3306/dbname" % quote(