nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: conan-io/conan
Pull request #18363 (2025-05-26 15:06:05)

Fix _parse_error_threshold crash when some package was not found in the catalog.
Changelog: BugFix: Fix `_parse_error_threshold` crash when some package was not found in the catalog.
Docs: Omit

This was crashing

![image](https://github.com/user-attachments/assets/889ec994-b9e6-4948-8db0-1340db325c5f)

because of this entry:

```
'dav1d/1.4.3': {'error': {'details': "Package 'dav1d/1.4.3' not scanned: Not found."}}
```

to reproduce audit any dependency graph that has one dependency like this resulting in not found.



Patch:
diff --git a/conan/cli/commands/audit.py b/conan/cli/commands/audit.py
index 04adcc0f2..ddddad029 100644
--- a/conan/cli/commands/audit.py
+++ b/conan/cli/commands/audit.py
@@ -31,6 +31,8 @@ def _parse_error_threshold(result: dict, error_level: float) -> None:
     """
     if "conan_error" not in result:
         for ref in result["data"]:
+            if "vulnerabilities" not in result["data"][ref]:
+                continue
             for edge in result["data"][ref]["vulnerabilities"]["edges"]:
                 preferred_base_score = float(edge["node"]["cvss"].get("preferredBaseScore", 0.0))
                 if preferred_base_score >= error_level:


Test patch:
diff --git a/test/integration/command/test_audit.py b/test/integration/command/test_audit.py
index b7fad10e0..75d5dd19b 100644
--- a/test/integration/command/test_audit.py
+++ b/test/integration/command/test_audit.py
@@ -387,3 +387,26 @@ def test_audit_scan_threshold_error(severity_level, threshold, should_fail):
             if threshold is None:
                 threshold = "9.0"
             assert f"ERROR: The package foobar/0.1.0 has a CVSS score {severity_level} and exceeded the threshold severity level {threshold}" in tc.out
+
+def test_parse_error_crash_when_no_edges():
+    from conan.cli.commands.audit import _parse_error_threshold
+
+    scan_result = {
+        "data": {
+            # this used to crash because dav1d not having vulnerabilities field
+            "dav1d/1.4.3": {"error": {"details": "Package 'dav1d/1.4.3' not scanned: Not found."}},
+            "zlib/1.2.11": {
+                "vulnerabilities": {
+                    "totalCount": 1,
+                    "edges": [
+                        {"node": {"cvss": {"preferredBaseScore": 7.0}}}
+                    ]
+                }
+            }
+        }
+    }
+
+    _parse_error_threshold(scan_result, error_level=5.0)
+    assert "conan_error" in scan_result
+    assert "zlib/1.2.11" in scan_result["conan_error"]
+    assert "7.0" in scan_result["conan_error"]
Repository: conan-io/conan
Pull request #18430 (2025-06-09 13:04:09)

Less verbose text upload
Changelog: Fix: Do not output upload-urls on basic text `conan upload` output.
Docs: Omit

To try to avoid excess of information for a regular conan upload on cli
![image](https://github.com/user-attachments/assets/8318ac8d-18f6-4c49-92e5-11d5ea592d04)




Patch:
diff --git a/conan/cli/commands/upload.py b/conan/cli/commands/upload.py
index 696cda874..0338002c9 100644
--- a/conan/cli/commands/upload.py
+++ b/conan/cli/commands/upload.py
@@ -23,6 +23,7 @@ def summary_upload_list(results):
                     v.pop("info", None)
                     v.pop("timestamp", None)
                     v.pop("files", None)
+                    v.pop("upload-urls", None)
                     upload_value = v.pop("upload", None)
                     if upload_value is not None:
                         msg = "Uploaded" if upload_value else "Skipped, already in server"


Test patch:
diff --git a/test/integration/command/upload/upload_test.py b/test/integration/command/upload/upload_test.py
index 633682087..45e64ebe3 100644
--- a/test/integration/command/upload/upload_test.py
+++ b/test/integration/command/upload/upload_test.py
@@ -571,7 +571,7 @@ def test_upload_json_output():
     }
 
 
-def test_upload_dry_run_json_output():
+def test_upload_dry_run_output():
     c = TestClient(default_server_user=True)
     c.save({"conanfile.py": GenConanfile("liba", "0.1").with_settings("os")
                                                        .with_shared_option(False)})
@@ -606,3 +606,9 @@ def test_upload_dry_run_json_output():
             "checksum": sha1sum(prev["files"]["conanmanifest.txt"])
         }
     }
+
+    # check we don't have anything about the upload-urls in the text formatter
+    c.run("upload * -r=default -c --dry-run")
+    assert "upload-urls" not in c.stdout
+    assert "url:" not in c.stdout
+    assert "checksum:" not in c.stdout
Repository: conan-io/conan
Pull request #18495 (2025-06-19 10:30:59)

fix detection of riscv64 cpu in Meson toolchain (#18490)
Changelog:  Bugfix: fix detection of riscv64 cpu in Meson toolchain (#18490)


- [x] Refer to the issue that supports this Pull Request.
- [x] I've read the [Contributing guide](https://github.com/conan-io/conan/blob/develop2/.github/CONTRIBUTING.md).
- [x] I've followed the PEP8 style guides for Python code.



Patch:
diff --git a/conan/tools/meson/helpers.py b/conan/tools/meson/helpers.py
index fcf49fd40..a6ea07a65 100644
--- a/conan/tools/meson/helpers.py
+++ b/conan/tools/meson/helpers.py
@@ -53,7 +53,7 @@ _meson_cpu_family_map = {
     'x86': ('x86', 'x86', 'little'),
     'x86_64': ('x86_64', 'x86_64', 'little'),
     'riscv32': ('riscv32', 'riscv32', 'little'),
-    'riscv64': ('riscv64', 'riscv32', 'little')
+    'riscv64': ('riscv64', 'riscv64', 'little')
 }
 
 


Test patch:
diff --git a/test/integration/toolchains/meson/test_mesontoolchain.py b/test/integration/toolchains/meson/test_mesontoolchain.py
index c1a7e8306..699da0a5f 100644
--- a/test/integration/toolchains/meson/test_mesontoolchain.py
+++ b/test/integration/toolchains/meson/test_mesontoolchain.py
@@ -748,6 +748,32 @@ def test_cross_x86_64_to_x86():
     assert "cpu = 'x86'" in cross  # This is the host machine
 
 
+def test_cross_x86_64_to_riscv32():
+    """
+    https://github.com/conan-io/conan/issues/18490
+    """
+    c = TestClient()
+    c.save({"conanfile.py": GenConanfile().with_settings("os", "compiler", "arch", "build_type")})
+    c.run("install . -g MesonToolchain -s os=Linux -s arch=riscv32 -s:b arch=x86_64")
+    assert not os.path.exists(os.path.join(c.current_folder, MesonToolchain.native_filename))
+    cross = c.load(MesonToolchain.cross_filename)
+    assert "cpu = 'x86_64'" in cross  # This is the build machine
+    assert "cpu = 'riscv32'" in cross  # This is the host machine
+
+
+def test_cross_x86_64_to_riscv64():
+    """
+    https://github.com/conan-io/conan/issues/18490
+    """
+    c = TestClient()
+    c.save({"conanfile.py": GenConanfile().with_settings("os", "compiler", "arch", "build_type")})
+    c.run("install . -g MesonToolchain -s os=Linux -s arch=riscv64 -s:b arch=x86_64")
+    assert not os.path.exists(os.path.join(c.current_folder, MesonToolchain.native_filename))
+    cross = c.load(MesonToolchain.cross_filename)
+    assert "cpu = 'x86_64'" in cross  # This is the build machine
+    assert "cpu = 'riscv64'" in cross  # This is the host machine
+
+
 def test_conf_extra_apple_flags():
     host = textwrap.dedent("""
     [settings]
Repository: conan-io/conan
Pull request #18552 (2025-06-27 10:13:11)

better error message for wrong cpp_info.requires
Changelog: Fix: Better error message when an incorrect ``cpp_info.requires`` is defined
Docs: Omit

Close https://github.com/conan-io/conan/issues/18550



Patch:
diff --git a/conan/internal/model/cpp_info.py b/conan/internal/model/cpp_info.py
index bf60b1b24..3d6fab03f 100644
--- a/conan/internal/model/cpp_info.py
+++ b/conan/internal/model/cpp_info.py
@@ -836,7 +836,7 @@ class CppInfo:
                 if r not in ret:
                     ret.append(r)
         # Then split the names
-        ret = [r.split("::") if "::" in r else (None, r) for r in ret]
+        ret = [r.split("::", 1) if "::" in r else (None, r) for r in ret]
         return ret
 
     def deduce_full_cpp_info(self, conanfile):


Test patch:
diff --git a/test/integration/test_components_error.py b/test/integration/test_components_error.py
index bc27f58a5..8d9250089 100644
--- a/test/integration/test_components_error.py
+++ b/test/integration/test_components_error.py
@@ -167,3 +167,26 @@ def test_unused_tool_requirement():
     t.run('create top.py --name=top2 --version=version')
     t.run('create consumer.py --name=wrong --version=version')
     # This runs without crashing, because it is not chcking that top::other doesn't exist
+
+
+def test_component_double_colon_error_message():
+    c = TestClient()
+    t2 = textwrap.dedent("""
+        from conan import ConanFile
+
+        class t2Conan(ConanFile):
+            name = "t2"
+            version = "0.1.0"
+            requires = "t1/0.1.0"
+            def package_info(self):
+                self.cpp_info.requires.append("t1::comp1::other")
+        """)
+
+    c.save({"t1/conanfile.py": GenConanfile("t1", "0.1.0"),
+            "t2/conanfile.py": t2,
+            "t2/test_package/conanfile.py": GenConanfile().with_settings("build_type")
+                                                          .with_generator("CMakeDeps")
+                                                          .with_test("pass")})
+    c.run("create t1")
+    c.run("create t2", assert_error=True)
+    assert "Component 't1::comp1::other' not found in 't1' package requirement" in c.out
Repository: rochacbruno/dynaconf
Pull request #75 (2018-07-30 16:32:31)

Fix in 'dynaconf/base.py' for __getitem__ method
```python
def __getitem__(self, item):
        """Allow getting variables as dict keys `settings['KEY']`"""
        value = self.get(item)
        if not value:    # Problem here !
            raise KeyError('{0} does not exists'.format(item))
        return value
```
This code don't work for integer or boolean arguments/parameters (in validation step) if there are set to 0 or False.
The condition `if not value` return True if value={0, False} then raise an exception (not wanted).
A simple fix on the condition prevent this behaviour => `if value is None`



Patch:
diff --git a/.gitignore b/.gitignore
index e098612..0d281b5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
+#
+.pytest_cache/
+
 # Byte-compiled / optimized / DLL files
 __pycache__/
 *.py[cod]
diff --git a/dynaconf/VERSION b/dynaconf/VERSION
index 21e8796..ee90284 100644
--- a/dynaconf/VERSION
+++ b/dynaconf/VERSION
@@ -1,1 +1,1 @@
-1.0.3
+1.0.4
diff --git a/dynaconf/base.py b/dynaconf/base.py
index bebef2b..3eba1b8 100644
--- a/dynaconf/base.py
+++ b/dynaconf/base.py
@@ -189,7 +189,7 @@ class Settings(object):
     def __getitem__(self, item):
         """Allow getting variables as dict keys `settings['KEY']`"""
         value = self.get(item)
-        if not value:
+        if value is None:
             raise KeyError('{0} does not exists'.format(item))
         return value
 


Test patch:
diff --git a/tests/test_validators.py b/tests/test_validators.py
index 8a76d29..03e6a8a 100644
--- a/tests/test_validators.py
+++ b/tests/test_validators.py
@@ -16,6 +16,8 @@ PRESIDENT = 'Lula'
 PROJECT = 'hello_world'
 SALARY = 2000
 WORKS = 'validator'
+ZERO = 0
+FALSE = false
 
 [development]
 MYSQL_HOST = 'development.com'
@@ -102,7 +104,18 @@ def test_validators(tmpdir):
         ),
         Validator('PORT',
                   must_exist=True, ne=8000,
-                  when=Validator('MYSQL_HOST', eq='localhost'))
+                  when=Validator('MYSQL_HOST', eq='localhost')),
+        #
+        Validator(
+            'ZERO',
+            is_type_of=int,
+            eq=0,
+        ),
+        Validator(
+            'FALSE',
+            is_type_of=bool,
+            eq=False,
+        ),
     )
 
     assert settings.validators.validate() is None
Repository: rochacbruno/dynaconf
Pull request #225 (2019-09-05 20:51:07)

Improve validators to use `from_env` method

codecov[bot]: # [Codecov](https://codecov.io/gh/rochacbruno/dynaconf/pull/225?src=pr&el=h1) Report
> Merging [#225](https://codecov.io/gh/rochacbruno/dynaconf/pull/225?src=pr&el=desc) into [master](https://codecov.io/gh/rochacbruno/dynaconf/commit/7287fae4d133f82950829fb605dfe8d57fd30ef7?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/rochacbruno/dynaconf/pull/225/graphs/tree.svg?width=650&token=GXszVzJcqW&height=150&src=pr)](https://codecov.io/gh/rochacbruno/dynaconf/pull/225?src=pr&el=tree)

```diff
@@          Coverage Diff          @@
##           master   #225   +/-   ##
=====================================
  Coverage     100%   100%           
=====================================
  Files          18     18           
  Lines         769    769           
=====================================
  Hits          769    769
```


| [Impacted Files](https://codecov.io/gh/rochacbruno/dynaconf/pull/225?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [dynaconf/validator.py](https://codecov.io/gh/rochacbruno/dynaconf/pull/225/diff?src=pr&el=tree#diff-ZHluYWNvbmYvdmFsaWRhdG9yLnB5) | `100% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/rochacbruno/dynaconf/pull/225?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/rochacbruno/dynaconf/pull/225?src=pr&el=footer). Last update [7287fae...7562019](https://codecov.io/gh/rochacbruno/dynaconf/pull/225?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/dynaconf/validator.py b/dynaconf/validator.py
index fc35b7b..d0e4ac6 100644
--- a/dynaconf/validator.py
+++ b/dynaconf/validator.py
@@ -109,10 +109,10 @@ class Validator(object):
             return
 
         for env in self.envs:
-            with settings.using_env(env):
-                self._validate_items(settings, env)
+            self._validate_items(settings.from_env(env))
 
-    def _validate_items(self, settings, env):
+    def _validate_items(self, settings, env=None):
+        env = env or settings.current_env
         for name in self.names:
             exists = settings.exists(name)
 


Test patch:
diff --git a/tests/test_validators.py b/tests/test_validators.py
index 6daad46..aea45eb 100644
--- a/tests/test_validators.py
+++ b/tests/test_validators.py
@@ -167,7 +167,7 @@ def test_no_reload_on_single_env(tmpdir, mocker):
     settings = LazySettings(
         ENV_FOR_DYNACONF="DEVELOPMENt", SETTINGS_FILE_FOR_DYNACONF=str(tmpfile)
     )
-    using_env = mocker.patch.object(settings, "using_env")
+    using_env = mocker.patch.object(settings, "from_env")
 
     settings.validators.register(same_env_validator)
     settings.validators.validate()
Repository: redis/redis-py
Pull request #3290 (2024-06-25 08:57:05)

Fixes CAE-333
The bug uncovered that the init method of the base class did override the initialization of the socket_timeout parameter.

This was fixed by moving `super().__init__(**kwargs)` before setting the timeout and path properties.

In addition, a test case was added.


Patch:
diff --git a/redis/connection.py b/redis/connection.py
index f745ecc1..728c2212 100644
--- a/redis/connection.py
+++ b/redis/connection.py
@@ -909,9 +909,9 @@ class UnixDomainSocketConnection(AbstractConnection):
     "Manages UDS communication to and from a Redis server"
 
     def __init__(self, path="", socket_timeout=None, **kwargs):
+        super().__init__(**kwargs)
         self.path = path
         self.socket_timeout = socket_timeout
-        super().__init__(**kwargs)
 
     def repr_pieces(self):
         pieces = [("path", self.path), ("db", self.db)]


Test patch:
diff --git a/tests/test_connect.py b/tests/test_connect.py
index 71986dd8..d7ca04b6 100644
--- a/tests/test_connect.py
+++ b/tests/test_connect.py
@@ -98,6 +98,23 @@ def test_tcp_ssl_tls12_custom_ciphers(tcp_address, ssl_ciphers):
     _assert_connect(conn, tcp_address, certfile=certfile, keyfile=keyfile)
 
 
+"""
+Addresses bug CAE-333 which uncovered that the init method of the base
+class did override the initialization of the socket_timeout parameter.
+"""
+
+
+def test_unix_socket_with_timeout():
+    conn = UnixDomainSocketConnection(socket_timeout=1000)
+
+    # Check if the base class defaults were taken over.
+    assert conn.db == 0
+
+    # Verify if the timeout and the path is set correctly.
+    assert conn.socket_timeout == 1000
+    assert conn.path == ""
+
+
 @pytest.mark.ssl
 @pytest.mark.skipif(not ssl.HAS_TLSv1_3, reason="requires TLSv1.3")
 def test_tcp_ssl_version_mismatch(tcp_address):
Repository: redis/redis-py
Pull request #3293 (2024-06-25 14:17:30)

[5.0] Fixes CAE-333
#3290 


Patch:
diff --git a/redis/connection.py b/redis/connection.py
index 346ff3aa..8645656d 100644
--- a/redis/connection.py
+++ b/redis/connection.py
@@ -818,9 +818,9 @@ class UnixDomainSocketConnection(AbstractConnection):
     "Manages UDS communication to and from a Redis server"
 
     def __init__(self, path="", socket_timeout=None, **kwargs):
+        super().__init__(**kwargs)
         self.path = path
         self.socket_timeout = socket_timeout
-        super().__init__(**kwargs)
 
     def repr_pieces(self):
         pieces = [("path", self.path), ("db", self.db)]
diff --git a/setup.py b/setup.py
index 4a157ea1..92f2ef97 100644
--- a/setup.py
+++ b/setup.py
@@ -8,7 +8,7 @@ setup(
     long_description_content_type="text/markdown",
     keywords=["Redis", "key-value store", "database"],
     license="MIT",
-    version="5.0.6",
+    version="5.0.7",
     packages=find_packages(
         include=[
             "redis",


Test patch:
diff --git a/tests/test_connect.py b/tests/test_connect.py
index fcc1a052..ec686540 100644
--- a/tests/test_connect.py
+++ b/tests/test_connect.py
@@ -96,6 +96,23 @@ def test_tcp_ssl_tls12_custom_ciphers(tcp_address, ssl_ciphers):
     _assert_connect(conn, tcp_address, certfile=certfile, keyfile=keyfile)
 
 
+"""
+Addresses bug CAE-333 which uncovered that the init method of the base
+class did override the initialization of the socket_timeout parameter.
+"""
+
+
+def test_unix_socket_with_timeout():
+    conn = UnixDomainSocketConnection(socket_timeout=1000)
+
+    # Check if the base class defaults were taken over.
+    assert conn.db == 0
+
+    # Verify if the timeout and the path is set correctly.
+    assert conn.socket_timeout == 1000
+    assert conn.path == ""
+
+
 @pytest.mark.ssl
 @pytest.mark.skipif(not ssl.HAS_TLSv1_3, reason="requires TLSv1.3")
 def test_tcp_ssl_version_mismatch(tcp_address):
Repository: bitcoin-core/secp256k1
Pull request #819 (2020-09-18 11:40:16)

Enable -Wundef warning


Patch:
diff --git a/configure.ac b/configure.ac
index 6fe8984..33c705c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -67,7 +67,7 @@ esac
 
 CFLAGS="-W $CFLAGS"
 
-warn_CFLAGS="-std=c89 -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-unused-function -Wno-long-long -Wno-overlength-strings"
+warn_CFLAGS="-std=c89 -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wundef -Wno-unused-function -Wno-long-long -Wno-overlength-strings"
 saved_CFLAGS="$CFLAGS"
 CFLAGS="$warn_CFLAGS $CFLAGS"
 AC_MSG_CHECKING([if ${CC} supports ${warn_CFLAGS}])


Test patch:
diff --git a/src/valgrind_ctime_test.c b/src/valgrind_ctime_test.c
index e676a83..3169e36 100644
--- a/src/valgrind_ctime_test.c
+++ b/src/valgrind_ctime_test.c
@@ -9,19 +9,19 @@
 #include "assumptions.h"
 #include "util.h"
 
-#if ENABLE_MODULE_ECDH
+#ifdef ENABLE_MODULE_ECDH
 # include "include/secp256k1_ecdh.h"
 #endif
 
-#if ENABLE_MODULE_RECOVERY
+#ifdef ENABLE_MODULE_RECOVERY
 # include "include/secp256k1_recovery.h"
 #endif
 
-#if ENABLE_MODULE_EXTRAKEYS
+#ifdef ENABLE_MODULE_EXTRAKEYS
 # include "include/secp256k1_extrakeys.h"
 #endif
 
-#if ENABLE_MODULE_SCHNORRSIG
+#ifdef ENABLE_MODULE_SCHNORRSIG
 #include "include/secp256k1_schnorrsig.h"
 #endif
 
@@ -37,11 +37,11 @@ int main(void) {
     unsigned char key[32];
     unsigned char sig[74];
     unsigned char spubkey[33];
-#if ENABLE_MODULE_RECOVERY
+#ifdef ENABLE_MODULE_RECOVERY
     secp256k1_ecdsa_recoverable_signature recoverable_signature;
     int recid;
 #endif
-#if ENABLE_MODULE_EXTRAKEYS
+#ifdef ENABLE_MODULE_EXTRAKEYS
     secp256k1_keypair keypair;
 #endif
 
@@ -81,7 +81,7 @@ int main(void) {
     CHECK(ret);
     CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature));
 
-#if ENABLE_MODULE_ECDH
+#ifdef ENABLE_MODULE_ECDH
     /* Test ECDH. */
     VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
     ret = secp256k1_ecdh(ctx, msg, &pubkey, key, NULL, NULL);
@@ -89,7 +89,7 @@ int main(void) {
     CHECK(ret == 1);
 #endif
 
-#if ENABLE_MODULE_RECOVERY
+#ifdef ENABLE_MODULE_RECOVERY
     /* Test signing a recoverable signature. */
     VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
     ret = secp256k1_ecdsa_sign_recoverable(ctx, &recoverable_signature, msg, key, NULL, NULL);
@@ -129,7 +129,7 @@ int main(void) {
     CHECK(ret);
 
     /* Test keypair_create and keypair_xonly_tweak_add. */
-#if ENABLE_MODULE_EXTRAKEYS
+#ifdef ENABLE_MODULE_EXTRAKEYS
     VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
     ret = secp256k1_keypair_create(ctx, &keypair, key);
     VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
@@ -142,7 +142,7 @@ int main(void) {
     CHECK(ret == 1);
 #endif
 
-#if ENABLE_MODULE_SCHNORRSIG
+#ifdef ENABLE_MODULE_SCHNORRSIG
     VALGRIND_MAKE_MEM_UNDEFINED(key, 32);
     ret = secp256k1_keypair_create(ctx, &keypair, key);
     VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
Repository: Scille/umongo
Pull request #175 (2019-03-08 08:48:06)

Round datetimes to milliseconds in LocalDateTimeField
Forgotten in https://github.com/Scille/umongo/pull/172.


Patch:
diff --git a/umongo/fields.py b/umongo/fields.py
index 1532a68..e262a03 100644
--- a/umongo/fields.py
+++ b/umongo/fields.py
@@ -181,8 +181,12 @@ class LocalDateTimeField(BaseField, ma_fields.LocalDateTime):
 
     def _deserialize(self, value, attr, data):
         if isinstance(value, datetime):
-            return value
-        return super()._deserialize(value, attr, data)
+            ret = value
+        else:
+            ret = super()._deserialize(value, attr, data)
+        # MongoDB stores datetimes with a millisecond precision.
+        # Don't keep more precision in the object than in the database.
+        return ret.replace(microsecond=round(ret.microsecond, -3))
 
 
 # class TimeField(BaseField, ma_fields.Time):


Test patch:
diff --git a/tests/test_fields.py b/tests/test_fields.py
index c0cb704..22d14d4 100644
--- a/tests/test_fields.py
+++ b/tests/test_fields.py
@@ -150,6 +150,7 @@ class TestFields(BaseTest):
 
         class MySchema(EmbeddedSchema):
             a = fields.DateTimeField()
+            b = fields.LocalDateTimeField()
 
         s = MySchema(strict=True)
         data, _ = s.load({'a': datetime(2016, 8, 6)})
@@ -161,10 +162,14 @@ class TestFields(BaseTest):
         with pytest.raises(ValidationError):
             s.load({'a': "dummy"})
 
-        # Test DateTimeField rounds to milliseconds
+        # Test DateTimeField and LocalDateTimeField round to milliseconds
         s = MySchema()
-        data, _ = s.load({'a': datetime(2016, 8, 6, 12, 30, 30, 123456)})
+        data, _ = s.load({
+            'a': datetime(2016, 8, 6, 12, 30, 30, 123456),
+            'b': datetime(2016, 8, 6, 12, 30, 30, 123456),
+        })
         assert data['a'].microsecond == 123000
+        assert data['b'].microsecond == 123000
 
     def test_strictdatetime(self):