GithubHelp home page GithubHelp logo

pokidovea / immobilus Goto Github PK

View Code? Open in Web Editor NEW
14.0 14.0 2.0 101 KB

A simple time freezing tool for python tests

License: Apache License 2.0

Makefile 0.63% Python 99.37%
decorators freezing mock python-tests time

immobilus's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Forkers

imankulov rioran

immobilus's Issues

Unexpected behavior with time.time

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?

Timezone aware

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.

Unexpected result with time.mktime

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.

Doesn't work with datetime.now() calls with an argument (timezone)

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.

immobilus is incompatible with logging.Formatter()

Hi @pokidovea! Just found one issue of using immobilius fake functions as class attributes, in particular in the logging.Formatter class.

Issue

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.

Case without patching

# 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>

Case with patching

# 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>>

Workaround

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'

Proper solution

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 unexpected results

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

Wrong `__add__` and `__sub__` logic for FakeDate

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 on installing with C locale

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 

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.