Skip to content

Commit

Permalink
Add time function (#129)
Browse files Browse the repository at this point in the history
* Add Time function in pywintypes

Add adapted tests from pywin32 in separate folder

* run pywin32 tests on ci

* Fix flake8 errors
  • Loading branch information
itziakos authored Apr 24, 2024
1 parent 31bdaf6 commit 83be1e3
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ jobs:
- name: Test on ${{ matrix.python-version }} 64-bit
run: |
coverage run -p -m haas -v win32ctypes
coverage run -p -m haas -v pywin32-tests
pip install --upgrade cffi
coverage run -p -m haas -v win32ctypes
coverage run -p -m haas -v pywin32-tests
env:
PYTHONFAULTHANDLER: 1
- name: Set up Python ${{ matrix.python-version }}
Expand All @@ -47,8 +49,10 @@ jobs:
- name: test on ${{ matrix.python-version }} 32-bit
run: |
coverage run -p -m haas -v win32ctypes
coverage run -p -m haas -v pywin32-tests
pip install --upgrade cffi
coverage run -p -m haas -v win32ctypes
coverage run -p -m haas -v pywin32-tests
env:
PYTHONFAULTHANDLER: 1
- name: Upload Coverage info
Expand Down
89 changes: 89 additions & 0 deletions pywin32-tests/test_pywintypes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#
# Tests addapted from the test_pywintypes.py of pywin32 to test the
# win32ctypes implementation
#
import os
import sys
import unittest
import contextlib
import tempfile
import shutil
import faulthandler
import datetime
import time

from win32ctypes import pywin32
from win32ctypes.pywin32.pywintypes import error

class TestPyWINTypes(unittest.TestCase):

# the pywin32ctypes implementation
module = pywin32.pywintypes

def testPyTimeFormat(self):
struct_current = time.localtime()
pytime_current = self.module.Time(struct_current)
# try and test all the standard parts of the format
# Note we used to include '%Z' testing, but that was pretty useless as
# it always returned the local timezone.
format_strings = "%a %A %b %B %c %d %H %I %j %m %M %p %S %U %w %W %x %X %y %Y"
for fmt in format_strings.split():
v1 = pytime_current.Format(fmt)
v2 = time.strftime(fmt, struct_current)
self.assertEqual(v1, v2, "format %s failed - %r != %r" % (fmt, v1, v2))

def testPyTimePrint(self):
# This used to crash with an invalid, or too early time.
# We don't really want to check that it does cause a ValueError
# (as hopefully this wont be true forever). So either working, or
# ValueError is OK.
try:
t = self.module.Time(-2)
t.Format()
except ValueError:
return

def testTimeInDict(self):
d = {}
d["t1"] = self.module.Time(1)
self.assertEqual(d["t1"], self.module.Time(1))

def testPyTimeCompare(self):
t1 = self.module.Time(100)
t1_2 = self.module.Time(100)
t2 = self.module.Time(101)

self.assertEqual(t1, t1_2)
self.assertTrue(t1 <= t1_2)
self.assertTrue(t1_2 >= t1)

self.assertNotEqual(t1, t2)
self.assertTrue(t1 < t2)
self.assertTrue(t2 > t1)

def testPyTimeCompareOther(self):
t1 = self.module.Time(100)
t2 = None
self.assertNotEqual(t1, t2)

def testTimeTuple(self):
now = datetime.datetime.now() # has usec...
# timetuple() lost usec - pt must be <=...
pt = self.module.Time(now.timetuple())
# *sob* - only if we have a datetime object can we compare like this.
if isinstance(pt, datetime.datetime):
self.assertTrue(pt <= now)

def testTimeTuplems(self):
now = datetime.datetime.now() # has usec...
tt = now.timetuple() + (now.microsecond // 1000,)
pt = self.module.Time(tt)
# we can't compare if using the old type, as it loses all sub-second res.
if isinstance(pt, datetime.datetime):
# but even with datetime, we lose sub-millisecond.
expectedDelta = datetime.timedelta(milliseconds=1)
self.assertTrue(-expectedDelta < (now - pt) < expectedDelta)

def testPyTimeFromTime(self):
t1 = self.module.Time(time.time())
self.assertTrue(self.module.Time(t1) is t1)
30 changes: 30 additions & 0 deletions win32ctypes/pywin32/pywintypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#
""" A module which supports common Windows types. """
import contextlib
import collections
import time
from datetime import datetime as _datetime


class error(Exception):
Expand Down Expand Up @@ -35,3 +38,30 @@ def pywin32error():
if not hasattr(exception, 'function'):
exception.function = 'unknown'
raise error(exception.winerror, exception.function, exception.strerror)


class datetime(_datetime):

def Format(self, fmt='%c'):
return self.strftime(fmt)


def Time(value):
if isinstance(value, datetime):
return value
elif hasattr(value, 'timetuple'):
timetuple = value.timetuple()
return datetime.fromtimestamp(time.mktime(timetuple))
elif isinstance(value, collections.abc.Sequence):
time_value = time.mktime(value[:9])
if len(value) == 10:
time_value += value[9] / 1000.0
return datetime.fromtimestamp(time_value)
else:
try:
return datetime.fromtimestamp(value)
except OSError as error:
if error.errno == 22:
raise ValueError(error.strerror)
else:
raise

0 comments on commit 83be1e3

Please sign in to comment.