Module rsyscall.time
#include <time.h>
Expand source code Browse git
"`#include <time.h>`"
from __future__ import annotations
from rsyscall._raw import lib, ffi # type: ignore
from rsyscall.struct import Struct
import typing as t
from decimal import Decimal
import decimal
import math
from dataclasses import dataclass
NSEC_PER_SEC = 1_000_000_000
@dataclass
class Timespec:
"""struct timespec, as used by several time-related system-calls.
This struct specifies time with nanosecond precision, but there's no good standard way
in Python to represent such times. The growing standard is to use an integer number of
nanoseconds, but that's easy to confuse with an integer number of seconds, and most
functions don't take number-of-nanoseconds, they take number-of-seconds.
So, this class supports conversion to and from a bunch of other formats.
See the proposal of using Decimal to represent nanosecond timestamps:
https://www.python.org/dev/peps/pep-0410/
https://www.python.org/dev/peps/pep-0564/
https://vstinner.github.io/python37-pep-564-nanoseconds.html
The rejection of that proposal by Guido:
https://mail.python.org/pipermail/python-dev/2012-February/116837.html
https://bugs.python.org/issue23084
"""
sec: int
nsec: int
def to_decimal(self) -> Decimal:
raise NotImplementedError
def to_nanos(self) -> int:
raise NotImplementedError
def _to_cffi_dict(self) -> t.Dict[str, int]:
return {
"tv_sec": self.sec,
"tv_nsec": self.nsec,
}
def to_bytes(self) -> bytes:
return bytes(ffi.buffer(ffi.new('struct timespec const*', self._to_cffi_dict())))
T = t.TypeVar('T', bound='Timespec')
@classmethod
def from_float(cls: t.Type[T], value: t.Union[float, Decimal, Timespec]) -> T:
if isinstance(value, Timespec):
return cls(value.sec, value.nsec)
elif isinstance(value, Decimal):
frac, i = decimal.getcontext().divmod(value, Decimal(1))
return cls(int(i), int(frac*NSEC_PER_SEC))
else:
fractional, integer = math.modf(value)
return cls(int(integer), int(fractional*NSEC_PER_SEC))
@classmethod
def from_nanos(cls: t.Type[T], nsec: int) -> T:
raise NotImplementedError
@classmethod
def from_cffi(cls: t.Type[T], cffi_value: t.Any) -> T:
return cls(cffi_value.tv_sec, cffi_value.tv_nsec)
@classmethod
def from_bytes(cls: t.Type[T], data: bytes) -> T:
struct = ffi.cast('struct timespec*', ffi.from_buffer(data))
return cls.from_cffi(struct)
@classmethod
def sizeof(cls) -> int:
return ffi.sizeof('struct timespec')
@dataclass
class Itimerspec(Struct):
interval: Timespec
value: Timespec
def __init__(self, interval: t.Union[float, Decimal, Timespec],
value: t.Union[float, Decimal, Timespec]) -> None:
self.interval = Timespec.from_float(interval)
self.value = Timespec.from_float(interval)
def _to_cffi_dict(self) -> t.Dict[str, t.Dict[str, int]]:
return {
"it_interval": self.interval._to_cffi_dict(),
"it_value": self.value._to_cffi_dict(),
}
def to_bytes(self) -> bytes:
return bytes(ffi.buffer(ffi.new('struct itimerspec const*', self._to_cffi_dict())))
T = t.TypeVar('T', bound='Itimerspec')
@classmethod
def from_bytes(cls: t.Type[T], data: bytes) -> T:
struct = ffi.cast('struct itimerspec*', ffi.from_buffer(data))
return cls(Timespec.from_cffi(struct.it_interval), Timespec.from_cffi(struct.it_value))
@classmethod
def sizeof(cls) -> int:
return ffi.sizeof('struct itimerspec')
#### Tests ####
from unittest import TestCase
class TestTime(TestCase):
def test_timespec(self) -> None:
initial = Timespec.from_float(Decimal('4.1'))
output = Timespec.from_bytes(initial.to_bytes())
self.assertEqual(initial, output)
def test_itimerspec(self) -> None:
initial = Itimerspec(Timespec.from_float(Decimal('1.2')), Timespec.from_float(Decimal('3.4')))
output = Itimerspec.from_bytes(initial.to_bytes())
self.assertEqual(initial, output)
Classes
class Timespec (sec: int, nsec: int)
-
struct timespec, as used by several time-related system-calls.
This struct specifies time with nanosecond precision, but there's no good standard way in Python to represent such times. The growing standard is to use an integer number of nanoseconds, but that's easy to confuse with an integer number of seconds, and most functions don't take number-of-nanoseconds, they take number-of-seconds.
So, this class supports conversion to and from a bunch of other formats.
See the proposal of using Decimal to represent nanosecond timestamps:
https://www.python.org/dev/peps/pep-0410/ https://www.python.org/dev/peps/pep-0564/ https://vstinner.github.io/python37-pep-564-nanoseconds.html
The rejection of that proposal by Guido:
https://mail.python.org/pipermail/python-dev/2012-February/116837.html https://bugs.python.org/issue23084
Expand source code Browse git
@dataclass class Timespec: """struct timespec, as used by several time-related system-calls. This struct specifies time with nanosecond precision, but there's no good standard way in Python to represent such times. The growing standard is to use an integer number of nanoseconds, but that's easy to confuse with an integer number of seconds, and most functions don't take number-of-nanoseconds, they take number-of-seconds. So, this class supports conversion to and from a bunch of other formats. See the proposal of using Decimal to represent nanosecond timestamps: https://www.python.org/dev/peps/pep-0410/ https://www.python.org/dev/peps/pep-0564/ https://vstinner.github.io/python37-pep-564-nanoseconds.html The rejection of that proposal by Guido: https://mail.python.org/pipermail/python-dev/2012-February/116837.html https://bugs.python.org/issue23084 """ sec: int nsec: int def to_decimal(self) -> Decimal: raise NotImplementedError def to_nanos(self) -> int: raise NotImplementedError def _to_cffi_dict(self) -> t.Dict[str, int]: return { "tv_sec": self.sec, "tv_nsec": self.nsec, } def to_bytes(self) -> bytes: return bytes(ffi.buffer(ffi.new('struct timespec const*', self._to_cffi_dict()))) T = t.TypeVar('T', bound='Timespec') @classmethod def from_float(cls: t.Type[T], value: t.Union[float, Decimal, Timespec]) -> T: if isinstance(value, Timespec): return cls(value.sec, value.nsec) elif isinstance(value, Decimal): frac, i = decimal.getcontext().divmod(value, Decimal(1)) return cls(int(i), int(frac*NSEC_PER_SEC)) else: fractional, integer = math.modf(value) return cls(int(integer), int(fractional*NSEC_PER_SEC)) @classmethod def from_nanos(cls: t.Type[T], nsec: int) -> T: raise NotImplementedError @classmethod def from_cffi(cls: t.Type[T], cffi_value: t.Any) -> T: return cls(cffi_value.tv_sec, cffi_value.tv_nsec) @classmethod def from_bytes(cls: t.Type[T], data: bytes) -> T: struct = ffi.cast('struct timespec*', ffi.from_buffer(data)) return cls.from_cffi(struct) @classmethod def sizeof(cls) -> int: return ffi.sizeof('struct timespec')
Class variables
var sec : int
var nsec : int
var T
Static methods
def from_float(value: t.Union[float, Decimal, Timespec]) ‑> T
-
Expand source code Browse git
@classmethod def from_float(cls: t.Type[T], value: t.Union[float, Decimal, Timespec]) -> T: if isinstance(value, Timespec): return cls(value.sec, value.nsec) elif isinstance(value, Decimal): frac, i = decimal.getcontext().divmod(value, Decimal(1)) return cls(int(i), int(frac*NSEC_PER_SEC)) else: fractional, integer = math.modf(value) return cls(int(integer), int(fractional*NSEC_PER_SEC))
def from_nanos(nsec: int) ‑> T
-
Expand source code Browse git
@classmethod def from_nanos(cls: t.Type[T], nsec: int) -> T: raise NotImplementedError
def from_cffi(cffi_value: t.Any) ‑> T
-
Expand source code Browse git
@classmethod def from_cffi(cls: t.Type[T], cffi_value: t.Any) -> T: return cls(cffi_value.tv_sec, cffi_value.tv_nsec)
def from_bytes(data: bytes) ‑> T
-
Expand source code Browse git
@classmethod def from_bytes(cls: t.Type[T], data: bytes) -> T: struct = ffi.cast('struct timespec*', ffi.from_buffer(data)) return cls.from_cffi(struct)
def sizeof() ‑> int
-
Expand source code Browse git
@classmethod def sizeof(cls) -> int: return ffi.sizeof('struct timespec')
Methods
def to_decimal(self) ‑> decimal.Decimal
-
Expand source code Browse git
def to_decimal(self) -> Decimal: raise NotImplementedError
def to_nanos(self) ‑> int
-
Expand source code Browse git
def to_nanos(self) -> int: raise NotImplementedError
def to_bytes(self) ‑> bytes
-
Expand source code Browse git
def to_bytes(self) -> bytes: return bytes(ffi.buffer(ffi.new('struct timespec const*', self._to_cffi_dict())))
class Itimerspec (interval: t.Union[float, Decimal, Timespec], value: t.Union[float, Decimal, Timespec])
-
Itimerspec(interval: 't.Union[float, Decimal, Timespec]', value: 't.Union[float, Decimal, Timespec]') -> 'None'
Expand source code Browse git
@dataclass class Itimerspec(Struct): interval: Timespec value: Timespec def __init__(self, interval: t.Union[float, Decimal, Timespec], value: t.Union[float, Decimal, Timespec]) -> None: self.interval = Timespec.from_float(interval) self.value = Timespec.from_float(interval) def _to_cffi_dict(self) -> t.Dict[str, t.Dict[str, int]]: return { "it_interval": self.interval._to_cffi_dict(), "it_value": self.value._to_cffi_dict(), } def to_bytes(self) -> bytes: return bytes(ffi.buffer(ffi.new('struct itimerspec const*', self._to_cffi_dict()))) T = t.TypeVar('T', bound='Itimerspec') @classmethod def from_bytes(cls: t.Type[T], data: bytes) -> T: struct = ffi.cast('struct itimerspec*', ffi.from_buffer(data)) return cls(Timespec.from_cffi(struct.it_interval), Timespec.from_cffi(struct.it_value)) @classmethod def sizeof(cls) -> int: return ffi.sizeof('struct itimerspec')
Ancestors
Class variables
var interval : Timespec
var value : Timespec
var T
Inherited members
class TestTime (methodName='runTest')
-
A class whose instances are single test cases.
By default, the test code itself should be placed in a method named 'runTest'.
If the fixture may be used for many test cases, create as many test methods as are needed. When instantiating such a TestCase subclass, specify in the constructor arguments the name of the test method that the instance is to execute.
Test authors should subclass TestCase for their own tests. Construction and deconstruction of the test's environment ('fixture') can be implemented by overriding the 'setUp' and 'tearDown' methods respectively.
If it is necessary to override the init method, the base class init method must always be called. It is important that subclasses should not change the signature of their init method, since instances of the classes are instantiated automatically by parts of the framework in order to be run.
When subclassing TestCase, you can set these attributes: * failureException: determines which exception will be raised when the instance's assertion methods fail; test methods raising this exception will be deemed to have 'failed' rather than 'errored'. * longMessage: determines whether long messages (including repr of objects used in assert methods) will be printed on failure in addition to any explicit message passed. * maxDiff: sets the maximum length of a diff in failure messages by assert methods using difflib. It is looked up as an instance attribute so can be configured by individual tests if required.
Create an instance of the class that will use the named test method when executed. Raises a ValueError if the instance does not have a method with the specified name.
Expand source code Browse git
class TestTime(TestCase): def test_timespec(self) -> None: initial = Timespec.from_float(Decimal('4.1')) output = Timespec.from_bytes(initial.to_bytes()) self.assertEqual(initial, output) def test_itimerspec(self) -> None: initial = Itimerspec(Timespec.from_float(Decimal('1.2')), Timespec.from_float(Decimal('3.4'))) output = Itimerspec.from_bytes(initial.to_bytes()) self.assertEqual(initial, output)
Ancestors
- unittest.case.TestCase
Methods
def test_timespec(self) ‑> NoneType
-
Expand source code Browse git
def test_timespec(self) -> None: initial = Timespec.from_float(Decimal('4.1')) output = Timespec.from_bytes(initial.to_bytes()) self.assertEqual(initial, output)
def test_itimerspec(self) ‑> NoneType
-
Expand source code Browse git
def test_itimerspec(self) -> None: initial = Itimerspec(Timespec.from_float(Decimal('1.2')), Timespec.from_float(Decimal('3.4'))) output = Itimerspec.from_bytes(initial.to_bytes()) self.assertEqual(initial, output)