Skip to content

fix(python): preserve timestamp microsecond precision - #4190

Closed
Daomiyo wants to merge 1 commit into
apache:mainfrom
Daomiyo:fix/python-timestamp-precision
Closed

Daomiyo wants to merge 1 commit into
apache:mainfrom
Daomiyo:fix/python-timestamp-precision

Conversation

@Daomiyo

@Daomiyo Daomiyo commented Oct 21, 2026

Copy link
Copy Markdown

Draft contribution with automated validation completed. Contributor self-review, personal verification, and human-authored rationale remain pending; this is not ready for maintainer review under AI_POLICY.md.

Observed behavior

On the unmodified baseline, a UTC datetime ending in 1970-01-01T00:00:00.000249 is written with 248 microseconds instead of 249. Other dates also lose microseconds, and decoding the maximum Python datetime can overflow.

Automated implementation notes: preserve integer epoch seconds and microseconds separately in Python and Cython, retain local-time conversion for naive values, and decode the bounded fractional component with ties-to-even rounding. The existing 12-byte seconds/nanoseconds representation and public API are unchanged. Added tests inspect exact bytes and values; five Java/Python fixtures exercise both directions.

Automated validation

Validated local snapshot: d2f1d708ddc44492e7dadb5e0b2874df8455919c
Published branch uses this exact commit; all five remote file hashes match the validated manifest.
Base: 80bcf64e68defb2de70e8e9047a1bb5f5d050883

macOS arm64, CPython 3.12.13, NumPy 1.26.4, PyArrow 20.0.0, JDK 25.0.2, Maven 3.10.0. Source and native-extension fingerprints checked before the test run.

  • Full Python suite: pure mode 1091 passed / 35 skipped; Cython mode 1096 passed / 30 skipped. Arrow tests ran; remaining skips are Java-driven cases and mode-specific cases.
  • Java-driven PythonXlangTest plus PyCrossLanguageTest#testCrossLanguageSerializer: each mode 68 passed / 20 skipped / 0 failures. New timestamp cases executed; skips are existing duplicate exclusions and unsupported union cases.
  • Changed Python files pass Ruff format/check; Java test formatting and git diff --check pass.
  • Earlier focused timestamp regression run against the unmodified serializers: 20 failures / 26 passes per mode.
  • Windows execution was not performed. Its existing current-DST offset behavior is retained.

Commands, from python/:

ENABLE_FORY_CYTHON_SERIALIZATION=0 python -m pytest -q -ra .
ENABLE_FORY_CYTHON_SERIALIZATION=1 python -m pytest -q -ra .

From java/, after the reactor installation and clean test compilation, with the local Python environment on PATH, for MODE=0 and MODE=1:

FORY_PYTHON_JAVA_CI=1 ENABLE_FORY_CYTHON_SERIALIZATION=$MODE ENABLE_FORY_DEBUG_OUTPUT=1 mvn -B -ntp -pl fory-core test '-Dtest=org.apache.fory.xlang.PythonXlangTest,org.apache.fory.xlang.PyCrossLanguageTest#testCrossLanguageSerializer'

Benchmark

Adjacent baseline/change pairs with 120,000 loops × 8 values × 15 repetitions per case, identical frames, and matching before/after source/native fingerprints. These are local CPython 3.12 microbenchmarks. Earlier results are retained in the evidence archive.

Mode Case Operation Baseline ns/value Changed ns/value Change
Cython utc serialize 235.97 141.49 -40.04%
Cython utc deserialize 330.88 181.28 -45.21%
Cython offset serialize 359.28 257.78 -28.25%
Cython offset deserialize 326.81 183.25 -43.93%
Cython naive serialize 398.08 387.28 -2.71%
Cython naive deserialize 329.47 177.41 -46.15%
Cython pre_epoch serialize 232.29 140.07 -39.70%
Cython pre_epoch deserialize 323.59 179.61 -44.49%
Python utc serialize 1151.91 1102.96 -4.25%
Python utc deserialize 1043.34 1047.84 +0.43%
Python offset serialize 1359.34 1266.73 -6.81%
Python offset deserialize 1052.47 1029.19 -2.21%
Python naive serialize 1336.17 1338.39 +0.17%
Python naive deserialize 1056.54 1039.46 -1.62%
Python pre_epoch serialize 1195.15 1093.16 -8.53%
Python pre_epoch deserialize 1061.24 1054.32 -0.65%

AI Usage Disclosure

  • substantial_ai_assistance: yes
  • scope: investigation, implementation, tests, performance measurement, automated reviews, and these draft technical notes
  • affected_files_or_subsystems: Python/Cython timestamp serializers; Python serializer tests and Java/Python cross-language fixtures
  • ai_review: two fresh clean-context automated reviews on the validated local snapshot above reported no actionable findings. Human self-review has not occurred, so the required human-first final review sequence is not claimed complete.
  • ai_review_artifacts: automated workflow labels and exact diff identity are recorded below. They are preliminary to the project's required human-first sequence.
  • human_verification: pending. All checks described above were executed and inspected by the coding agent, not personally by the submitter.
  • performance_verification: adjacent baseline/change local microbenchmarks; raw measurements and before/after source/native fingerprints are prepared with the contribution artifacts.
  • provenance_license_confirmation: modifications are to existing Apache-licensed files and introduce no copied third-party code or new dependency; contributor confirmation remains pending.

Automated review records:

  • Fory-guided workflow /root/fory_fresh_guided_oct22: no actionable findings after inspecting all five files, repository guidance, arithmetic, timezone/fold semantics, C API bounds, protocol and test evidence.
  • Independent general workflow /root/fory_fresh_independent_oct22: no actionable findings after independently inspecting all five files, arithmetic, boundaries, compatibility and coverage.
  • Both reviewed the validated local snapshot/base above; retained local git diff SHA-256: 46c175d8c1baa4c8b7aaad72fc23a44addb1bedb2b842f2212ec0e85e2439312.

Remaining contributor steps

  • Disclose substantial AI assistance and distinguish automated checks from human checks.
  • Personally review all changed lines and explain the implementation and tradeoffs.
  • Personally run relevant checks and inspect results.
  • Supply human-authored rationale, risk assessment and review responses.
  • Complete the two-fresh-reviewer sequence after human self-review and persist final evidence.
  • Confirm provenance and license obligations before marking ready for review.

Retained automated evidence

Source fingerprints, raw test output, benchmark measurements, and preliminary automated review records:

fory-timestamp-verification.zip

@Daomiyo

Daomiyo commented Oct 22, 2026

Copy link
Copy Markdown
Author

Closing this draft because I won't be continuing work on it. Anyone interested is welcome to pick up the timestamp precision issue; the patch and automated validation artifacts above remain available as a starting point. The contributor self-review and personal verification listed above remain incomplete.

Automated CI triage for run 39639380150: seven jobs stopped during Python setup because Python 3.8 x64 was unavailable on Ubuntu 26.04. The remaining failure was compilation of the unchanged C++ ResultTest.Assignment test with -Werror=maybe-uninitialized, before the C++ tests ran; the validity of that warning remains unverified.

Thanks to anyone who takes this forward.

@Daomiyo Daomiyo closed this Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant