Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

gh-110850: Add PyTime_t C API#112135

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
vstinner wants to merge3 commits intopython:mainfromvstinner:pytime_api
Closed

Conversation

vstinner
Copy link
Member

@vstinnervstinner commentedNov 16, 2023
edited by github-actionsbot
Loading

Add PyTime_t API:

  • PyTime_t type.
  • PyTime_MIN and PyTime_MAX constants.
  • PyTime_AsSecondsDouble(), PyTime_GetMonotonicClock(), PyTime_GetPerfCounter() and PyTime_GetSystemClock() functions.

📚 Documentation preview 📚:https://cpython-previews--112135.org.readthedocs.build/

Copy link
Contributor

@colesburycolesbury left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

A few drive-by comments

* Monotonic clock
* Performance counter

Internally, operations like ``(t * k / q)`` with integers are implemented in a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This paragraph made more sense for someone reading the code than someone reading the docs and looking to use this API.

@vstinner
Copy link
MemberAuthor

@colesbury: I copied the long comment from the private header file as the documentation. I already had doubts about mentioning details of the internal C API which are not exposed in the public C API yet. I will reorganize the "public" documentation to only leave documentation relevant to the few functions made public.

encukou reacted with thumbs up emoji

the returned value is undefined, so that only the difference between the
results of consecutive calls is valid.

If reading the clock fails, silently ignore the error and return 0.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

We're adding new functions here, so shouldn't we let them report errors? I don't think silent failures are what you'd want for a new API. Why not return-1 (without exception) in the case of failures for all three get-time functions? Then users can decide themselves whether they want to handle or ignore the error. Or do you consider0 a safe error indicator?

@vstinner
Copy link
MemberAuthor

@scoder:

We're adding new functions here, so shouldn't we let them report errors? I don't think silent failures are what you'd want for a new API. Why not return -1 (without exception) in the case of failures for all three get-time functions? Then users can decide themselves whether they want to handle or ignore the error. Or do you consider 0 a safe error indicator?

Not being able to report errors isnot safe. The risk of error while reading time islow, whereas the cost of having to report errors to the caller while reading time ishigh. It makes code way more complicated.

There are some specific C extensions where we cannot even report errors, since the API doesn't let to report errors to the caller. One example if thePyThread_acquire_lock_timed() API. For example, one implementation uses:

_PyTime_tdeadline=_PyTime_Add(_PyTime_GetMonotonicClock(),timeout);_PyTime_AsTimespec_clamp(deadline,&abs_timeout);

It uses_PyTime_Add() and the_clamp function variant which clamp the result into [_PyTime_MIN; _PyTime_MAX] range, rather than raising an exception and report an error.

In existing code which doesn't use thePyTime API, do you know any code which actually check for errors? If yes, how are errors handled?

Since I designed and implemented PEP 418 in 2012, I paid a lot of attention to bug reports about "reading time". I only recall on bug report in Red Hat bug tracker of an application running in a sandbox and the sandbox blocked syscalls to read time. Well, it was more a sandbox configuration issue, than a bug in Python.

When I implemented PEP 418, I was scared of regressions, so I added a read the monotonic clock at Python startup: so Python was able to check for "read time" error at one place, and only one place. That's how I discovered the sandbox issue. Later, Iremoved these checks at startup. I decided that it's not worth it.

commit ae6cd7cfdab0599139002c526953d907696d9eefAuthor: Victor Stinner <vstinner@python.org>Date:   Mon Nov 16 16:08:05 2020 +0100    bpo-37205: time.time() cannot fail with fatal error (GH-23314)        time.time(), time.perf_counter() and time.monotonic() functions can    no longer fail with a Python fatal error, instead raise a regular    Python exception on failure.        Remove _PyTime_Init(): don't check system, monotonic and perf counter    clocks at startup anymore.        On error, _PyTime_GetSystemClock(), _PyTime_GetMonotonicClock() and    _PyTime_GetPerfCounter() now silently ignore the error and return 0.    They cannot fail with a Python fatal error anymore.        Add py_mach_timebase_info() and win_perf_counter_frequency()    sub-functions.

@vstinner
Copy link
MemberAuthor

@colesbury@scoder@serhiy-storchaka: Please review the updated PR.

  • I cleaned up the C API doc.
  • I renamed the functions to use shorter names.
  • I added dedicated tests to test_capi.test_time.
  • I kept aliases to old names for this PR to make the PR shorter and easier to review. I will remove the private aliases in a follow-up PR once this once is merged.

Copy link
Contributor

@colesburycolesbury left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

A few suggestions about the documentation below.

@vstinner
Copy link
MemberAuthor

A few suggestions about the documentation below.

@colesbury: Thanks, I applied your suggestions. Does the updated doc look better?

Functions
---------

.. c:function:: double PyTime_AsSecondsDouble(PyTime_t t)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

What is the rounding mode? Do we need an argument for specifying it?

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I don't know how to implement a rounding method on this function. I don't know how numbers are rounded. The function starts to lose precision at2**53 nanoseconds:

>>> x=2**53+1; y=int(_testcapi.PyTime_AsSecondsDouble(x)*1e9); f"ulp(x)={math.ulp(x)} and {y-x=}"'ulp(x)=2.0 and y-x=-1'

In short, the function is implemented as:

defPyTime_AsSecondsDouble(t):returnfloat(t)/1e9

@vstinner
Copy link
MemberAuthor

I have too many things on my plate. I prefer to close the PR for now.

@vstinnervstinner deleted the pytime_api branchDecember 20, 2023 12:41
@vstinnervstinner restored the pytime_api branchJanuary 18, 2024 16:17
@vstinnervstinner reopened thisJan 18, 2024
Add PyTime_t API:* PyTime_t type.* PyTime_MIN and PyTime_MAX constants.* PyTime_AsSecondsDouble(), PyTime_Monotonic(),  PyTime_PerfCounter() and PyTime_GetSystemClock() functions.Changes:* Add Include/cpython/pytime.h header.* Add Modules/_testcapi/time.c and Lib/test/test_capi/test_time.py  tests on these new functions.* Rename _PyTime_GetMonotonicClock() to PyTime_Monotonic().* Rename _PyTime_GetPerfCounter() to PyTime_PerfCounter().* Rename _PyTime_GetSystemClock() to PyTime_Time().* Rename _PyTime_AsSecondsDouble() to PyTime_AsSecondsDouble().* Rename _PyTime_MIN to PyTime_MIN.* Rename _PyTime_MAX to PyTime_MAX.
@vstinner
Copy link
MemberAuthor

I reopened my PR since#110850 issue is now marked as a release blocker issue. I rebased my PR on main.

@vstinner
Copy link
MemberAuthor

I created a C API Working Group issue:capi-workgroup/decisions#8

Comment on lines +87 to +92
if (PyModule_AddObject(m, "PyTime_MIN", PyLong_FromLongLong(PyTime_MIN)) < 0) {
return 1;
}
if (PyModule_AddObject(m, "PyTime_MAX", PyLong_FromLongLong(PyTime_MAX)) < 0) {
return 1;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
if (PyModule_AddObject(m,"PyTime_MIN",PyLong_FromLongLong(PyTime_MIN))<0) {
return1;
}
if (PyModule_AddObject(m,"PyTime_MAX",PyLong_FromLongLong(PyTime_MAX))<0) {
return1;
}
if (PyModule_Add(m,"PyTime_MIN",PyLong_FromLongLong(PyTime_MIN))<0) {
return-1;
}
if (PyModule_Add(m,"PyTime_MAX",PyLong_FromLongLong(PyTime_MAX))<0) {
return-1;
}

Comment on lines +20 to +21
A timestamp or duration in nanoseconds represented as a 64-bit signed
integer.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

At the C-API WG issue, you say that the units are supposed to be an implementation detail.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Oh, now I'm confused. I don't recall the exact history of this PR that I wrote 3 months ago.

When I wrote that API 10 years ago, I tried hard to not expose the "unit" (1 nanosecond). In practice, it was always 1 nanosecond, even if on Windows, clocks only have a resolution of 100 nanoseconds in the best case.

Maybe it's time to stick to nanoseconds. On Linux,timespec,clock_gettime(),nanosleep() have a resolution of 1 nanosecond. I don't know any operating system API using a better resolution.

So well, we should stick to 1 nanosecond to avoid any confusion. So creating aPyTime_t of 1 nanosecond is justPyTime_t one_ns = 1;. No "from nanoseconds" or "to nanoseconds" are needed. It makes the API simpler to use (so less error prone).

colesbury and erlend-aasland reacted with thumbs up emoji
@vstinner
Copy link
MemberAuthor

I close this PR: the C API Working Group is against an API which cannot fail.

Instead,@encukou modified to PR as PRgh-115215 which can report errors.

@vstinnervstinner deleted the pytime_api branchFebruary 12, 2024 16:04
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@encukouencukouencukou left review comments

@scoderscoderscoder left review comments

@colesburycolesburycolesbury left review comments

@erlend-aaslanderlend-aaslanderlend-aasland left review comments

@serhiy-storchakaserhiy-storchakaserhiy-storchaka approved these changes

@pablogsalpablogsalAwaiting requested review from pablogsal

@pgansslepganssleAwaiting requested review from pgansslepganssle is a code owner

@abalkinabalkinAwaiting requested review from abalkinabalkin is a code owner

@kumaraditya303kumaraditya303Awaiting requested review from kumaraditya303

Assignees
No one assigned
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

6 participants
@vstinner@encukou@scoder@colesbury@serhiy-storchaka@erlend-aasland

[8]ページ先頭

©2009-2025 Movatter.jp