pokidovea / immobilus Goto Github PK
View Code? Open in Web Editor NEWA simple time freezing tool for python tests
License: Apache License 2.0
A simple time freezing tool for python tests
License: Apache License 2.0
My system is GMT+2, and it seems time.time
returns local time when I think it should return UTC time.
with immobilus.immobilus("1970-01-01 00:00:00"):
print(time.time())
# -3600.0 is printed
# 0.0 is expected
What do you think?
Hi. It would be great if immobilus had a tz_offset
parameter, like the freezegun one, so for instance datetime.now
and datetime.utcnow
could return different values.
A new one :) The time.mktime
function takes a local time argument and returns a timestamp.
# dt.py
import immobilus, datetime, time
with immobilus.immobilus("1970-01-01 00:00:00"):
timetuple = datetime.datetime.now().timetuple()
print(timetuple)
mktime = time.mktime(timetuple)
print(mktime)
$ env TZ=UTC-1 python dt.py
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=-1)
-3600.0
The expected value of time.mktime
is 0
but it seems the system timezone is used over the tz_offset
value.
The datetime.now()
calls in my code use the tz
argument with the timezone
class added in Python 3.2, similar to:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
Immobilus isn't able to work with these, since it overrides now()
with a function that doesn't take any arguments.
Hi @pokidovea! Just found one issue of using immobilius fake functions as class attributes, in particular in the logging.Formatter class.
The stdlib formatter contains following code
class Formatter(object):
converter = time.localtime
The converter is called to convert log record timestamp to ASCII string. The problem is, time.localtime
(which has type "builtin_function_or_method") and fake_localtime
(which has type "function") behave differently as class attributes: the latter is bound with a parent class instance on initialization.
# Python 3.6.2 (default, Aug 2 2017, 15:33:18)
>>> import logging
>>> logging.Formatter('%(asctime)s').format(logging.makeLogRecord({}))
'2018-06-22 18:19:20,435'
>>> logging.Formatter.converter
<built-in function localtime>
>>> logging.Formatter().converter
<built-in function localtime>
# Python 3.6.2 (default, Aug 2 2017, 15:33:18)
>>> from immobilus import immobilus
>>> import logging
>>> logging.Formatter('%(asctime)s').format(logging.makeLogRecord({}))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/roman/.pyenv/versions/3.6.2/lib/python3.6/logging/__init__.py", line 577, in format
record.asctime = self.formatTime(record, self.datefmt)
File "/Users/roman/.pyenv/versions/3.6.2/lib/python3.6/logging/__init__.py", line 513, in formatTime
ct = self.converter(record.created)
TypeError: fake_localtime() takes from 0 to 1 positional arguments but 2 were given
>>> logging.Formatter.converter
<function fake_localtime at 0x10ebe3950>
>>> logging.Formatter().converter
<bound method fake_localtime of <logging.Formatter object at 0x10e9ccac8>>
For myself I found a workaround which kind of works, but solves only this specific case
>>> from immobilus import immobilus
>>> import logging
>>> logging.Formatter.converter = staticmethod(logging.Formatter.converter)
>>> logging.Formatter('%(asctime)s').format(logging.makeLogRecord({}))
'2018-06-22 18:20:46,534'
Probably, the only generalized solution is to turn fake_localtime to an object with a __get__
method, always returning itself (disallowing binding), but I haven't experimented with this.
datetime.datetime.fromtimestamp
should return a local date, but the system timezone is used and the tz_offset
parameter seems ignored.
# fromtimestamp.py
import immobilus, datetime, time
with immobilus.immobilus("1970-01-01 00:00:01"):
print(datetime.datetime.fromtimestamp(0))
with immobilus.immobilus("1970-01-01 00:00:01", tz_offset=6):
print(datetime.datetime.fromtimestamp(0))
# immobilus behavior
$ env TZ=UTC-12 python fromtimestamp.py
1970-01-01 12:00:00
1970-01-01 12:00:00
# Expected results
1970-01-01 00:00:00
1970-01-01 06:00:00
I think the two functions here https://github.com/pokidovea/immobilus/blob/master/immobilus/logic.py#L76-L93 should use date
instead of datetime
. Otherwise we get:
In [1]: import immobilus
In [2]: from datetime import date, timedelta
In [3]: timedelta(days=1) + date(2017, 1, 1)
Out[3]: datetime.date(2017, 1, 2)
In [4]: date(2017, 1, 1) - timedelta(days=1)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-4-f61d14feefaf> in <module>()
----> 1 date(2017, 1, 1) - timedelta(days=1)
/usr/local/lib/python2.7/dist-packages/immobilus/logic.pyc in __sub__(self, other)
83
84 def __sub__(self, other):
---> 85 result = datetime.__sub__(self, other)
86
87 if result is NotImplemented:
TypeError: descriptor '__sub__' requires a 'datetime.datetime' object but received a 'FakeDate'
In [4]: date(2017, 1, 1) + timedelta(days=1)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-5-11f9d8e78586> in <module>()
----> 1 date(2017, 1, 1) + timedelta(days=1)
/usr/local/lib/python2.7/dist-packages/immobilus/logic.pyc in __add__(self, other)
75
76 def __add__(self, other):
---> 77 result = datetime.__add__(self, other)
78
79 if result is NotImplemented:
TypeError: descriptor '__add__' requires a 'datetime.datetime' object but received a 'FakeDate'
By monkey patching as follows, it works as expected:
import immobilus
from datetime import date
def __add__(self, other):
result = immobilus.logic.date.__add__(self, other)
if result is NotImplemented:
return result
return self.from_datetime(result)
immobilus.logic.FakeDate.__add__ = __add__
def __sub__(self, other):
result = immobilus.logic.date.__sub__(self, other)
if result is NotImplemented:
return result
if isinstance(result, date):
return self.from_datetime(result)
else:
return result
immobilus.logic.FakeDate.__sub__ = __sub__
UnicodeDecodeError when installing immobilus using pip module when the locale is set to C (for example on installing using ansible pip module).
LC_ALL=C pip install -r ./requirements.txt
Results:
Collecting immobilus==1.4.0 (from -r ./requirements.txt (line 45))
Using cached immobilus-1.4.tar.gz
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/tmp/pip-build-v8ng1rqn/immobilus/setup.py", line 6, in <module>
long_description = f.read()
File "/usr/lib/python3.6/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 6766: ordinal not in range(128)
This is probably related to having non-ascii character in contributes name from README.rst
--
If anyone else runs into the same error, explicitly set locale in your ansible task
environment:
LC_ALL: en_US.UTF-8
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.