virtualenv notification center is None

Issue #239 new
Sean Farley
created an issue

After much crawling around the internet, it seems that the reason this returns None:

Python 2.7.14 (default, Sep 27 2017, 12:15:00)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.37)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from Foundation import NSUserNotificationCenter
>>> print NSUserNotificationCenter.defaultUserNotificationCenter()
None

is due to the fact that the virtualenv doesn't respect that python was built as a framework. Copying the system (or macports or homebrew) python to the virtualenv fixes the problem but that seems absurd.

What exactly is going on here? I'm trying to use pyobjc in a project which has its own requirements.txt file. Requiring each user to do this hack seems wrong; what exactly is going on? Is this something that pyobjc can even fix? Or does virtualenv need an upstream patch?

Comments (6)

  1. Ronald Oussoren repo owner

    The problem is that a number of Apple APIs, and likely including NotificationCenter, only work in application bundles (although there's appearently a workaround using undocumented private APIs).

    You don't notice this when using the normal interpreter in a framework build because that ensures the right environment is available by stuffing the real interpreter in an application bundle ($prefix/bin/python is a small wrapper that execs the real interpreter that's stuffed into a Python.app inside the framework).

    In the end this means that this cannot be fixed in PyObjC, but needs to be fixed in virtualenv.

    P.S. venv (included with python3) does work correctly.

  2. Sean Farley reporter

    Alas, I'm on python 2.7 for quite a while (due to Mercurial). Thanks for the answer! Do you know if this has been attempted in virtualenv? I saw some discussion of symlinking (which does work) but it seemed to be rejected for portability reasons.

  3. Ronald Oussoren repo owner

    To return to this issue: I thought this was at one point fixed in virtualenv, but possibly only in a local branch :-(. The python launcher itself does have some support for virtualenv (see Mac/Tools/pythonw.c in the CPython tree, in particular the comment above get_python_path).

    The following file structure in a virtualenv should work:

    VIRTUALENV/
    bin/
    python <- Copy of {sys.prefix}/bin/python (not of {sys.executable}
    .Python <- Copy of the shared library (already done)
    .Resources/Python.app/Contents/MacOS/Python <- Copy of sys.executable

    Both executables should be linked to the .Python file (rewriting the link command as is already done by virtualenv).

    In a framework build this should result in a the same behavior as you get outside of a virtualenv.

    I don't think this should affect portability, this can be done in the already existing conditional code for framework builds.

  4. Sean Farley reporter

    I think the difficulty is in making a package (as I was trying to do) so that I can put this as a dependency in requirements.txt. Having to instruct users to do something manual is going to lead to a lot of confusion :-/

    All-in-all, I absolutely think this should be fixed in virtualenv but browsing their open issue seems like walking down a road filled with skeletons.

  5. Ronald Oussoren repo owner

    Getting support for framework builds in wasn't too hard.

    I don't know if I ever get around to creating a patch for this myself, but this shouldn't be too hard (I'm just pressed for time as it is).

  6. Log in to comment