Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

py 1.5 breaks freezegun on Windows #169

Closed
Kwpolska opened this issue Nov 15, 2017 · 17 comments · Fixed by #171
Closed

py 1.5 breaks freezegun on Windows #169

Kwpolska opened this issue Nov 15, 2017 · 17 comments · Fixed by #171

Comments

@Kwpolska
Copy link

My AppVeyor (Windows) tests recently started failing with this:

================================== FAILURES ===================================
________________________ TestScheduling.test_get_date _________________________
c:\python36\lib\site-packages\freezegun\api.py:494: in wrapper
    with self:
c:\python36\lib\site-packages\freezegun\api.py:365: in __enter__
    return self.start()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <freezegun.api._freeze_time object at 0x052C2270>

    def start(self):
        if self.tick:
            time_to_freeze = TickingDateTimeFactory(self.time_to_freeze, real_datetime.now())
        else:
            time_to_freeze = FrozenDateTimeFactory(self.time_to_freeze)
    
        # Change the modules
        datetime.datetime = FakeDatetime
        datetime.date = FakeDate
        fake_time = FakeTime(time_to_freeze, time.time)
        fake_localtime = FakeLocalTime(time_to_freeze, time.localtime)
        fake_gmtime = FakeGMTTime(time_to_freeze, time.gmtime)
        fake_strftime = FakeStrfTime(time_to_freeze, time.strftime)
        time.time = fake_time
        time.localtime = fake_localtime
        time.gmtime = fake_gmtime
        time.strftime = fake_strftime
        uuid._uuid_generate_time = None
        uuid._UuidCreate = None
    
        copyreg.dispatch_table[real_datetime] = pickle_fake_datetime
        copyreg.dispatch_table[real_date] = pickle_fake_date
    
        # Change any place where the module had already been imported
        to_patch = [
            ('real_date', real_date, 'FakeDate', FakeDate),
            ('real_datetime', real_datetime, 'FakeDatetime', FakeDatetime),
            ('real_gmtime', real_gmtime, 'FakeGMTTime', fake_gmtime),
            ('real_localtime', real_localtime, 'FakeLocalTime', fake_localtime),
            ('real_strftime', real_strftime, 'FakeStrfTime', fake_strftime),
            ('real_time', real_time, 'FakeTime', fake_time),
        ]
        real_names = tuple(real_name for real_name, real, fake_name, fake in to_patch)
        self.fake_names = tuple(fake_name for real_name, real, fake_name, fake in to_patch)
        self.reals = dict((id(fake), real) for real_name, real, fake_name, fake in to_patch)
        fakes = dict((id(real), fake) for real_name, real, fake_name, fake in to_patch)
        add_change = self.undo_changes.append
    
        # Save the current loaded modules
        self.modules_at_start = set(sys.modules.keys())
    
        with warnings.catch_warnings():
            warnings.filterwarnings('ignore')
    
            for mod_name, module in list(sys.modules.items()):
                if mod_name is None or module is None:
                    continue
                elif mod_name.startswith(self.ignore):
                    continue
                elif (not hasattr(module, "__name__") or module.__name__ in ('datetime', 'time')):
                    continue
>               for module_attribute in dir(module):
E               ModuleNotFoundError: No module named 'syslog'

c:\python36\lib\site-packages\freezegun\api.py:421: ModuleNotFoundError
================ 1 failed, 202 passed in -133582692.64 seconds ================

I investigated a little, and I found out that this appears only with py 1.5.x. Rolling back to py==1.4.34 fixes the issue. Is this a bug in py or freezegun?

(see also: spulec/freezegun#214)

@nicoddemus
Copy link
Member

nicoddemus commented Nov 15, 2017

@Kwpolska unfortunately this is a bug in py, see #170 .

I will work on a fix ASAP.

@gvanrossum
Copy link

It's not just freezegun. It happened to the mypy project too, and we fixed it the same way. There's an AppVeyor support ticket but honestly I think the problem is here, in the py.log module -- it now unconditionally imports syslog which AFAICT is UNIX only -- it's in the doc section labeled "Unix specific services".

@nicoddemus
Copy link
Member

@gvanrossum your assessment is correct. At the time some refactoring was done, there was no proper Windows CI and that import escaped unnoticed.

@gvanrossum
Copy link

gvanrossum commented Nov 15, 2017 via email

@nicoddemus
Copy link
Member

@gvanrossum and @Kwpolska, 1.5.2 has been released with the fix, thanks again for the reports! 👍

gvanrossum added a commit to python/mypy that referenced this issue Nov 16, 2017
Fixes #4252 differently.

According to pytest-dev/py#169 (comment), py 1.5.2 has been pushed out that fixes this issue.
@Kwpolska
Copy link
Author

My build passes, thanks!

@pganssle
Copy link

@nicoddemus It seems like setup.py has changed to drop Python 3.3 support between the 1.5.0 release and 1.5.2 release. Was this intentional? It seems to be pinning my Python 3.3 Windows builds to the broken 1.5.0 build.

@nicoddemus
Copy link
Member

@pganssle thanks for writing. Are you having an error using 1.5.0 in py33, or are you just wondering if this was intentional?

It was intentional to drop support for py26 and py33 on 1.5.0, but we failed to add the proper metadata to 1.5.0 to indicate that, unfortunately. We were considering removing 1.5.0 from PyPI because >=1.5.1 is identical to it but with correct meta data, but we are reluctant to do that because it is considered a bad idea in general to pull releases from PyPI, but in this case might be the only solution.

cc @RonnyPfannschmidt

@pganssle
Copy link

pganssle commented Nov 16, 2017

@nicoddemus Yes, my build is breaking because 1.5.0 doesn't have this fix but does have the metadata wrong.

I believe you can just edit the metadata directly on PyPI though, irrespective of the release. Dropping Python 3.3 from the 1.5.0 release should also fix my build.

@nicoddemus
Copy link
Member

I believe you can just edit the metadata directly on PyPI though

That would be ideal, but I'm not sure it is possible: the metadata resides inside the package, and changing its contents is not possible (AFAIK).

Perhaps pulling it is the right solution.

@nicoddemus
Copy link
Member

nicoddemus commented Nov 16, 2017

I believe you can fix your build by explicitly pinning <1.5 btw (which is the proper solution because >1.5 drops 3.3 support).

@pganssle
Copy link

@nicoddemus Yes, I can try this, but the problem is that py is an indirect dependency, so it gets a bit complicated and I'd rather not be messing with it explicitly. Not to mention anything on Appveyor involves batch scripting, which is far from my forte...

I think you are right that pypi metadata is immutable once it's up there. I was a bit confused by this.

I think the traditional solution to "I need to pull a release" (though I doubt it will make a difference in this case) is to upload a .post1 version with the same version number. Not sure if the "which version can I download" logic will pick up the 3.3 trove classifier in the base 1.5.0 package and fall back to that, but if so, I think that even if you remove the 1.5.0 package, ==1.5.0 rules will still match 1.5.0.post1 (though I don't have time to test this right now).

@nicoddemus
Copy link
Member

@pganssle opened dateutil/dateutil#527 with a possible fix, please take a look.

@pganssle
Copy link

Thanks for the PR. I have a different approach that's more complicated but somewhat more limited. Either one will ultimately get removed when either the trove classifiers are fixed for 1.5.0 or whoever is including py as a direct dependency on Python 3.3 starts pinning. Later this afternoon I'll try and track that down and open an issue or PR on that repo.

@nicoddemus
Copy link
Member

OK sounds good. Sorry for not being able to help more because I'm at work at the moment and can't spare much time.

@nicoddemus
Copy link
Member

Btw, pytest itself depends on py and won't drop the dependency anytime soon.

@nicoddemus
Copy link
Member

nicoddemus commented Nov 16, 2017

Btw, pytest itself depends on py and won't drop the dependency anytime soon.

I just realized this might not be clear as I wanted: I mention this because you can probably safely add the py<1.5 restriction on py33 if pytest is also a dependency, because pytest won't be dropping py anytime soon, and by the time it does you probably will have dropped py33 yourself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants