Skip to content

Commit

Permalink
python api: allow timeval and timespec init with float/datetime
Browse files Browse the repository at this point in the history
  • Loading branch information
natoscott committed Oct 16, 2024
1 parent 4d00bb5 commit 347473c
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 13 deletions.
4 changes: 4 additions & 0 deletions qa/737.out
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ pmCtime from int: Mon Feb 3 04:46:19 2014
pmCtime from float: Mon Feb 3 04:46:19 2014
pmWhichZone: UTC
pmWhichZone: UTC
timeval from int: 1391402779.000
timeval from float: 1391402779.500
timespec from int: 1391402779.000
timespec from float: 1391402779.500
15 changes: 13 additions & 2 deletions qa/src/test_pcp_time.python
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env pmpython
#
# Copyright (C) 2014,2016 Red Hat.
# Copyright (C) 2014,2016,2024 Red Hat.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
Expand All @@ -13,7 +13,7 @@
# for more details.
#

""" Exercise the pmCtime and pmLocaltime interfaces """
""" Exercise pmCtime, pmLocaltime, timeval and timespec interfaces """

from pcp import pmapi
import time
Expand Down Expand Up @@ -44,3 +44,14 @@ print("pmCtime from float: %s" % str(context.pmCtime(sample_time_f)).rstrip
print("pmWhichZone: %s" % str(context.pmWhichZone()))
# https://bugzilla.redhat.com/show_bug.cgi?id=1352465
print("pmWhichZone: %s" % str(context.pmWhichZone()))

timevali = pmapi.timeval(sample_time_i)
timevalf = pmapi.timeval(sample_time_f)
print("timeval from int: %s" % timevali)
print("timeval from float: %s" % timevalf)

sample_time_f += 0.5 # sub-second component
timespeci = pmapi.timespec(sample_time_i)
timespecf = pmapi.timespec(sample_time_f)
print("timespec from int: %s" % timespeci)
print("timespec from float: %s" % timespecf)
44 changes: 33 additions & 11 deletions src/python/pcp/pmapi.py.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
""" Wrapper module for LIBPCP - the core Performace Co-Pilot API
#
# Copyright (C) 2012-2022 Red Hat
# Copyright (C) 2012-2024 Red Hat
# Copyright (C) 2009-2012 Michael T. Werner
#
# This file is part of the "pcp" module, the python interfaces for the
Expand Down Expand Up @@ -94,9 +94,11 @@ import os
import sys
import time
import errno
import datetime
import json

from datetime import datetime
from math import modf

# constants adapted from C header file <pcp/pmapi.h>
import cpmapi as c_api

Expand Down Expand Up @@ -227,8 +229,18 @@ class timeval(Structure):
_fields_ = [("tv_sec", c_time_t),
("tv_usec", c_suseconds_t)]

def __init__(self, sec=0, usec=0):
def __init__(self, sec=0, usec=None):
Structure.__init__(self)
if usec is None:
if isinstance(sec, datetime):
epoch = datetime.utcfromtimestamp(0)
sec = float((sec - epoch).total_seconds())
if isinstance(sec, float):
ts = modf(sec)
sec = int(ts[1])
usec = int(ts[0] * 1000000)
else:
usec = 0
self.tv_sec = sec
self.tv_usec = usec

Expand Down Expand Up @@ -270,8 +282,18 @@ class timespec(Structure):
_fields_ = [("tv_sec", c_time_t),
("tv_nsec", c_long)]

def __init__(self, sec=0, nsec=0):
def __init__(self, sec=0, nsec=None):
Structure.__init__(self)
if nsec is None:
if isinstance(sec, datetime):
epoch = datetime.utcfromtimestamp(0)
sec = float((sec - epoch).total_seconds())
if isinstance(sec, float):
ts = modf(sec)
sec = int(ts[1])
nsec = int(ts[0] * 1000000000)
else:
nsec = 0
self.tv_sec = sec
self.tv_nsec = nsec

Expand Down Expand Up @@ -2900,7 +2922,7 @@ class pmContext(object):
@staticmethod
def datetime_to_secs(value, precision=c_api.PM_TIME_SEC):
""" Convert datetime value to seconds of given precision """
tdt = value - datetime.datetime.fromtimestamp(0)
tdt = value - datetime.fromtimestamp(0)
if precision == c_api.PM_TIME_SEC:
tst = (tdt.microseconds + (tdt.seconds + tdt.days * 24.0 * 3600.0) * 10.0**6) / 10.0**6
elif precision == c_api.PM_TIME_MSEC:
Expand Down Expand Up @@ -3030,8 +3052,8 @@ class fetchgroup(object):
"""
ts = self.ctx.pmLocaltime(self.value.tv_sec)
us = int(self.value.tv_nsec) // 1000
dt = datetime.datetime(ts.tm_year+1900, ts.tm_mon+1, ts.tm_mday,
ts.tm_hour, ts.tm_min, ts.tm_sec, us, None)
dt = datetime(ts.tm_year+1900, ts.tm_mon+1, ts.tm_mday,
ts.tm_hour, ts.tm_min, ts.tm_sec, us, None)
return dt

class fetchgroup_timeval(object):
Expand All @@ -3054,8 +3076,8 @@ class fetchgroup(object):
"""
ts = self.ctx.pmLocaltime(self.value.tv_sec)
us = int(self.value.tv_usec)
dt = datetime.datetime(ts.tm_year+1900, ts.tm_mon+1, ts.tm_mday,
ts.tm_hour, ts.tm_min, ts.tm_sec, us, None)
dt = datetime(ts.tm_year+1900, ts.tm_mon+1, ts.tm_mday,
ts.tm_hour, ts.tm_min, ts.tm_sec, us, None)
return dt

# create the backward compatibility alias
Expand Down Expand Up @@ -3140,8 +3162,8 @@ class fetchgroup(object):

ts = self.ctx.pmLocaltime(self.times[i].tv_sec)
us = int(self.times[i].tv_nsec) // 1000
dt = datetime.datetime(ts.tm_year+1900, ts.tm_mon+1, ts.tm_mday,
ts.tm_hour, ts.tm_min, ts.tm_sec, us, None)
dt = datetime(ts.tm_year+1900, ts.tm_mon+1, ts.tm_mday,
ts.tm_hour, ts.tm_min, ts.tm_sec, us, None)
# nested lambda for proper i capture
# pylint: disable=cell-var-from-loop,unnecessary-direct-lambda-call
vv.append((dt,
Expand Down

0 comments on commit 347473c

Please sign in to comment.