From paul at paulromer.net Wed Nov 10 15:28:18 2021 From: paul at paulromer.net (Paul Romer) Date: Wed, 10 Nov 2021 15:28:18 -0500 Subject: [Pythonmac-SIG] Problems building a binary from cpython that can be installed in /Users/{USER}/Library Message-ID: I am new to this sig. I hope it is appropriate to pose the following detailed question to its members. Let me know if I have misunderstood. I'll provide a bit of background, specify the steps I took, then describe the two issues I'm facing on which I would welcome advice. ===================================================================== *Background: * I am trying to create a self-contained Python application that a user could download and run on MacOS that does not have Python 3 installed. I am aware that PyInstaller and py2app are alternative paths for creating self-contained apps and am pursuing them in parallel. The issue I want to describe here arose as part of experiments with the process for creating a binary for a recent version of Python (3.9.8) that can be installed under the user's home directory. /Users/{USER}/Library. According to the information in the cpython repository, it seems that it should be possible to build an installer for a full version of Python that can be installed someplace on a Mac other than the default location: /Library. In particular, one should be able to do this using build-installer.py in the Mac/BuildScript directory. *=====================================================================* *Steps I Took:* In the cpython directory I ran: > ./configure --enable-framework=/Users/{USER}/Library/Frameworks \ --enable-optimizations I confirmed that the Makefile included the line: CONFIG_ARGS= '--enable-framework=/Users/{USER}/Library/Frameworks' '--enable-optimizations' (I also tried replacing {USER} with the actual user on my system, 'admin'. This yielded the same results.) I put the external files OpenSSL, tcl/tck, ... (details below) that are required into the .../Universal/other-sources directory. I deleted my install of Python3.9 and backed-up and deleted all the files from /usr/local/bin Then from /Mac/BuildScript I ran > python3 build-installer.py \ --universal-archs=intel-64 \ --dep-target=11 Along the way, there were several warnings, but no errors. The end result is a dmg file: python-3.9.8+-macos12-2021-11-10.dmg ===================================================================== *Issues:* 1. I am not sure how to convert the dmg into a "macOS flat installer package" and would welcome any advice on this point. 2. But in any case, I do not think that an installer based on this dmg will allow an install in the Library of the user. When I inspect the dmg file, I find that the post-install scripts include references to the usual file location in /Library. For example, the script that runs after installing the framework has the lines: PYVER="3.9" FWK="/Library/Frameworks/Python.framework/Versions/3.9" The script that runs after installing the files for pip has the lines: PYVER="3.9" PYMAJOR="3" FWK="/Library/Frameworks/Python.framework/Versions/${PYVER}" RELFWKBIN="../../..${FWK}/bin" This suggests that I have misunderstood the instructions. So I would appreciate any advice on how to succeed on this path, or suggestions about alternative paths that might work. In particular, the alternative that might be feasible would be to use the work from https://github.com/codrsquad/portable-python This is a recent project, not the one with the same name that was abandoned that you'll find here: https://portablepython.com/ Thanks for reading through all this! ===================================================================== PS: Contents of my .../Universal/other-sources directory: -rw-r--r-- 1 admin staff 367573 Nov 10 00:53 ncurses-5.9-20120616-patch.sh.bz2 -rw-r--r-- 1 admin staff 2826473 Nov 10 00:53 ncurses-5.9.tar.gz -rw-r--r-- 1 admin staff 9834044 Nov 9 22:19 openssl-1.1.1l.tar.gz -rw-rw-rw-@ 1 admin staff 2956627 Nov 10 01:06 sqlite-autoconf-3350500.tar.gz -rw-rw-rw-@ 1 admin staff 10259009 Nov 9 22:55 tcl8.6.11-src.tar.gz -rw-rw-rw-@ 1 admin staff 4496914 Nov 10 00:37 tk8.6.11-src.tar.gz -rw-rw-rw-@ 1 admin staff 1490665 Nov 10 00:45 xz-5.2.3.tar.gz ===================================================================== Paul Romer paul at paulromer.net | paulromer.net | @paulromer -------------- next part -------------- An HTML attachment was scrubbed... URL: From ronaldoussoren at mac.com Thu Nov 11 08:41:04 2021 From: ronaldoussoren at mac.com (Ronald Oussoren) Date: Thu, 11 Nov 2021 14:41:04 +0100 Subject: [Pythonmac-SIG] ANN: PyObjC 8.0 Message-ID: A new macOS release means a new major release of PyObjC. I'm happy to announce that PyObjC 8 is available on PyPI with full support for macOS 12, including APIs introduced in that release. I've also been working on performance and code quality of the core bridge. There are significant speedups of the core bridge in PyObjC 8.0, and I have more ideas to reduce the performance difference between regular Python methods and calling Objective-C APIs. The release is a bit later than I would have liked, in part because I've been worrying about the covid-19 situation in Holland. Because of that I've spend some more time away from the computer. A full change log is included below. Backward incompatible changes In PyObjC 7 and earlier it was possible to leave out "output" arguments when calling a method with a Python implementation: class MyClass(NSObject): @objc.typedSelector(b"@@:o^@") def methodWithOutput_(self, a): return 1, 2 o = MyClass.alloc().init() print(o.methodWithOutput_()) This no longer works, it is always necessary to pass in all arguments, which was already true for methods implemented in Objective-C. That is: print(o.methodWithOutput_(None)) This change both simplifies the PyObjC code base and was required to cleanly implement vectorcall support (see the section on performance below). Removed bindings for InterfaceBuilderKit. This was a way to integrate with InterfaceBuilder in old versions of Xcode, but support for that was dropped before the release of Mac OS X 10.8. Bindings for the Objective-C runtime API related to "associated objects" is now enabled unconditionally. This will cause problems when running or building on macOS 10.6 or earlier. It is no longer possible to deploy to macOS 10.7 or earlier when you attempt to create a formal protocol. Protocol creation already failed on those platform due to lack of the required runtime API, and that will now result in a crash because PyObjC no longer checks for availability of that runtime API. GH-371: Remove manual bindings for a number of old CoreGraphics APIs The following functions are no longer available: CGDataProviderCreate CGDataProviderCreateDirectAccess These functions were removed as a public API in macOS 10.8, but were still available through PyObjC through old backward compatibility code. That code has now been removed. For compatibility with Python's socket APIs functions that return a "struct sockaddr" (either by reference or as a function result) will now encode the IP address as a string and not a bytes object. The (undocumented) API in pyobjc-api.h (used in some framework bindings to integratie with pyobjc-core) has changed in an incompatible way, in particular the API for "caller" functions now mostly mirrors the vectorcall convention. Adding a method with a double underscore name will now raise an exception at class definition time instead of silently not creating the Objective-C method. class AClass (NSObject): ... def __foo_bar__(self, a, b, c): pass MethodNamesClass.__foo_bar__ = __foo_bar__ Before PyObjC 8 this would add a __foo_bar__ selector to the Python representation of the class without adding a selector to the Objective-C class. Use objc.python_method to mark this as a python-only function. Upcoming incompatible changes The module PyObjCTools.Signals is deprecated and will be removed in PyObjC 9. objc.initFrameworkWrapper and objc.parseBridgeSupport are deprecated and will be removed in PyObjC 9. These functions implement support for ".bridgesupport" XML files, something that PyObjC hasn't used itself in a number of releases (in part because system versions of those files are at best incomplete). Performance Most performance changes use features introduced in Python 3.9, performance in older Python versions is unchanged except for the effects of general cleanup. Implement the "vectorcall" protocol for objc.function, objc.WeakRef, objc.selector, objc.IMP, objc.python_method. This reduces the interpreter overhead for calling instances of these objects. Implement Py_TPFLAGS_METHOD_DESCRIPTOR for objc.selector, objc.python_method. Use vectorcall in the method stub that forwards Objective-C calls to Python. Convert internal calls into Python to the vectorcall protocol (pyobjc-core) Add more optimized vectorcall implementation to :class:objc.function, objc.IMP and objc.selector for simpler callables. "Simpler" methods are those with a small number of plain arguments, although the definition of what's simple will evolve over time. Generic Implementation Quality GH-391: Fix some spelling errors found by the codespell tool. The codespell tool is also run as part of pre-commit hooks. GH-296: use clang-format for Objective-C code The Objective-C code for the various extensions has been reformatted using clang-format, and this enforced by a pre-commit hook. GH-374: Use pyupgrade to modernize the code base This is enforced by a pre-commit hook. GH-388: Added "nullability" attributes to Objectice-C sources for pyobjc-core. This gives the compiler and clang static analyzer more information that can be used to pinpoint possible bugs in the implementation. As a side effect of this a number of internal checks were strengthened, although most of them were for error conditions that should never happen. That said, this change also found a number of places where Python reference counts weren't updated properly, which may have led to refcount overflows in long running programs. Add more error checking to pyobjc-core to catch (very) unlikely error conditions. This is a side effect of the previous item. New features Updated framework bindings for macOS 12 New framework bindings for the following frameworks: AudioVideoBridging (introduced in macOS 10.8) DataDetection (introduced in macOS 12.0) IntentsUI (introduced in macOS 12.0) LocalAuthenticationEmbeddedUI (introduced in macOS 12.0) MailKit (introduced in macOS 12.0) MetricKit (introduced in macOS 12.0) ShazamKit (introduced in macOS 12.0) GH-318: Implement support for __class_getitem__ for Objective-C classes The result of this is that effectively all Objective-C classes can be used as generic classes, without runtime type checking. This is meant to be used with optional type checking (for example MyPy) Usage: def create_integers(count: int) -> NSArray[int]: return NSArray[int].arrayWithArray_([i for i in range(count)]) This requires typing stubs for framework bindings to be really useful, and those do not yet exist. Other changes and bugfixes GH-390: pyobjc-core is no longer linked with the Carbon framework. Due to implicit dependencies this also required a change to the Metal bindings: those now import AppKit instead of Foundation. PyObjC only ships "Universal 2" wheels for Python 3.8 and later. Those work with single-architecture builds of Python as well. PyObjC 8 only ships with source archives and "univeral2" binary wheels (Python 3.? and later). There are no longer "x86_64" binary wheels. The AVFoundation bindings (in pyobjc-framework-AVFoundation) now have an install dependency on the CoreAudio bindings (pyobjc-framework-CoreAudio). This is needed for a new API introduced in macOS 12. GH-371: Link extensions in the Quartz bindings to the Quartz frameworks A number of C extensions in the Quartz bindings package were not linked to a framework. Those now link to the Quartz framework. GH-378: Fix raising ImportError when doing from ApplicationServices import * The root cause for this were private classes in system frameworks that contain a dot in their name (for example Swift.DispatchQueueShim. Those names are both private and invalid attribute names. Creating protocols that contain methods that have a method signature containing PyObjC custom type encodings now works (those encodings are translated to the corresponding Objective-C encoding. Fix bindings for SKIndexCopyDocumentRefsForDocumentIDs, that binding didn't work due to a typo in the metadata. GH-365: The PyObjCTools namespace package no longer has an __init__.py file in the source tree (that is, the tree switches to implicit namespace packages instead of the older setuptools style for namespace packages). This primarily affects testing with recent versions of pip/setuptools (which seem to no longer install the __init__.py file for namespace packages). development-support/run-testsuite now uses venv instead of virtualenv. This removes a development dependency. PR-367: Tweak the code that calculates PyObjC_BUILD_RELEASE in the various setup.py files to deal with versions with more than two labels (can happen when building using Xcode 13 beta) PR by Eric Lin (Tzu Hsiang Lin), github user eric100lin. PyObjCTest.TestSupport now never uses "10.16" as the OS release but always uses the actual platform version, even when Python was compiled using an old SDK. Adjusted PyObjC testcases to check for 11.0 instead of 10.16 now that testsupport uses the real platform version. GH-385: Fix race condition the lazy importer When two threads simultaneously try to get an attribute from a framework binding one of them might fail with an attribute error because information for resolving the name was removed before actually resolving the name. Fix various issues with invalid indices in :class:objc.varlist Fix support for AF_UNIX in the support code for struct sockaddr. The implementation for opaque pointer types (such as the proxy for 'NSZone*') has switched to PyType_FromSpec. The objc.FSRef.from_path and objc.FSRef.as_pathname, methods now use the filesystem encoding instead of the default encoding. C string. This shouldn't affect any code, both encoding default to UTF-8 on macOS. Inheriting directly from objc.objc_object now raises TypeError instead of objc.InternalError. User code should always inherit from a Cocoa class. GH-354: Add an option to install all framework bindings, including those not relevant for the current platform. To use this: $ pip install 'pyobjc[allbindings]' Ronald ? Twitter / micro.blog: @ronaldoussoren Blog: https://blog.ronaldoussoren.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From barry at barrys-emacs.org Sun Nov 14 10:57:13 2021 From: barry at barrys-emacs.org (Barry Scott) Date: Sun, 14 Nov 2021 15:57:13 +0000 Subject: [Pythonmac-SIG] Problems building a binary from cpython that can be installed in /Users/{USER}/Library In-Reply-To: References: Message-ID: <9A38FFB6-CC12-4F25-9B41-D165BC7AFEB6@barrys-emacs.org> > On 10 Nov 2021, at 20:28, Paul Romer wrote: > > I am new to this sig. I hope it is appropriate to pose the following detailed question to its members. Let me know if I have misunderstood. > > I'll provide a bit of background, specify the steps I took, then describe the two issues I'm facing on which I would welcome advice. > > ===================================================================== > > Background: > I am trying to create a self-contained Python application that a user could download and run on MacOS that does not have Python 3 installed. I am aware that PyInstaller and py2app are alternative paths for creating self-contained apps and am pursuing them in parallel. > > The issue I want to describe here arose as part of experiments with the process for creating a binary for a recent version of Python (3.9.8) that can be installed under the user's home directory. > > /Users/{USER}/Library. > > According to the information in the cpython repository, it seems that it should be possible to build an installer for a full version of Python that can be installed someplace on a Mac other than the default location: /Library. In particular, one should be able to do this using > > build-installer.py > > in the > > Mac/BuildScript > > directory. > > ===================================================================== > > Steps I Took: > > In the cpython directory I ran: > > > ./configure --enable-framework=/Users/{USER}/Library/Frameworks \ > --enable-optimizations Why do you think you need to build CPYTHON at all? I use py3app with the python.org downloaded versions of python. > > I confirmed that the Makefile included the line: > > CONFIG_ARGS= '--enable-framework=/Users/{USER}/Library/Frameworks' '--enable-optimizations' > > (I also tried replacing {USER} with the actual user on my system, 'admin'. This yielded the same results.) > > I put the external files OpenSSL, tcl/tck, ... (details below) that are required into the > > .../Universal/other-sources > > directory. I deleted my install of Python3.9 and backed-up and deleted all the files from > > /usr/local/bin > > Then from > > /Mac/BuildScript > > I ran > > > python3 build-installer.py \ > --universal-archs=intel-64 \ > --dep-target=11 > > Along the way, there were several warnings, but no errors. The end result is a dmg file: > > python-3.9.8+-macos12-2021-11-10.dmg > > ===================================================================== > > Issues: > > 1. I am not sure how to convert the dmg into a "macOS flat installer package" and would welcome any advice on this point. You do not need to. All the user needs to do it drag the .app folder into (typically) /Applications. > > 2. But in any case, I do not think that an installer based on this dmg will allow an install in the Library of the user. When I inspect the dmg file, I find that the post-install scripts include references to the usual file location in /Library. For example, the script that runs after installing the framework has the lines: > > PYVER="3.9" > FWK="/Library/Frameworks/Python.framework/Versions/3.9" What post-install script? That's not something that py2app does. > > The script that runs after installing the files for pip has the lines: > > PYVER="3.9" > PYMAJOR="3" > FWK="/Library/Frameworks/Python.framework/Versions/${PYVER}" > RELFWKBIN="../../..${FWK}/bin" > > This suggests that I have misunderstood the instructions. So I would appreciate any advice on how to succeed on this path, or suggestions about alternative paths that might work. In particular, the alternative that might be feasible would be to use the work from > > https://github.com/codrsquad/portable-python > > This is a recent project, not the one with the same name that was abandoned that you'll find here: > > https://portablepython.com/ For Barry's Emacs I do 2 steps. 1. Build the .app bundle. 2. Build .dmg that has a bunch of files including the .app bundle. There may be a bit too much complexity but have look at how I build the .app bundle in https://github.com/barry-scott/BarrysEmacs/blob/master/Editor/PyQtBEmacs/build-macosx.sh and https://github.com/barry-scott/BarrysEmacs/blob/master/Editor/PyQtBEmacs/brand.setup-macosx.py I'm using PyQt not Tk. Barry > > > Thanks for reading through all this! > > > ===================================================================== > > PS: Contents of my .../Universal/other-sources directory: > > -rw-r--r-- 1 admin staff 367573 Nov 10 00:53 ncurses-5.9-20120616-patch.sh.bz2 > -rw-r--r-- 1 admin staff 2826473 Nov 10 00:53 ncurses-5.9.tar.gz > -rw-r--r-- 1 admin staff 9834044 Nov 9 22:19 openssl-1.1.1l.tar.gz > -rw-rw-rw-@ 1 admin staff 2956627 Nov 10 01:06 sqlite-autoconf-3350500.tar.gz > -rw-rw-rw-@ 1 admin staff 10259009 Nov 9 22:55 tcl8.6.11-src.tar.gz > -rw-rw-rw-@ 1 admin staff 4496914 Nov 10 00:37 tk8.6.11-src.tar.gz > -rw-rw-rw-@ 1 admin staff 1490665 Nov 10 00:45 xz-5.2.3.tar.gz > > ===================================================================== > > > Paul Romer > paul at paulromer.net | paulromer.net | @paulromer > > _______________________________________________ > Pythonmac-SIG maillist - Pythonmac-SIG at python.org > https://mail.python.org/mailman/listinfo/pythonmac-sig > unsubscribe: https://mail.python.org/mailman/options/Pythonmac-SIG -------------- next part -------------- An HTML attachment was scrubbed... URL: From pythonchb at gmail.com Sun Nov 14 12:50:14 2021 From: pythonchb at gmail.com (Christopher Barker) Date: Sun, 14 Nov 2021 09:50:14 -0800 Subject: [Pythonmac-SIG] Problems building a binary from cpython that can be installed in /Users/{USER}/Library In-Reply-To: <9A38FFB6-CC12-4F25-9B41-D165BC7AFEB6@barrys-emacs.org> References: <9A38FFB6-CC12-4F25-9B41-D165BC7AFEB6@barrys-emacs.org> Message-ID: I would very highly recommend that you not reinvent the wheel here. But if you really don't like the way Py2App or PyInstaller does it, then I wouldn't try to build the entire "normal" mac distribution anyway, and start at a lower level. Maybe look at homebrew for ideas? BTW -- there's a third option: conda and "conda constructor" -- might be worth a look. -CHB On Sun, Nov 14, 2021 at 7:57 AM Barry Scott wrote: > > > On 10 Nov 2021, at 20:28, Paul Romer wrote: > > I am new to this sig. I hope it is appropriate to pose the following > detailed question to its members. Let me know if I have misunderstood. > > I'll provide a bit of background, specify the steps I took, then describe > the two issues I'm facing on which I would welcome advice. > > ===================================================================== > > *Background: * > I am trying to create a self-contained Python application that a user > could download and run on MacOS that does not have Python 3 installed. I > am aware that PyInstaller and py2app are alternative paths for creating > self-contained apps and am pursuing them in parallel. > > The issue I want to describe here arose as part of experiments with the > process for creating a binary for a recent version of Python (3.9.8) that > can be installed under the user's home directory. > > /Users/{USER}/Library. > > According to the information in the cpython repository, it seems that it > should be possible to build an installer for a full version of Python that > can be installed someplace on a Mac other than the default location: > /Library. In particular, one should be able to do this using > > build-installer.py > > in the > > Mac/BuildScript > > directory. > > *=====================================================================* > > *Steps I Took:* > > In the cpython directory I ran: > > > ./configure --enable-framework=/Users/{USER}/Library/Frameworks \ > --enable-optimizations > > > Why do you think you need to build CPYTHON at all? > > I use py3app with the python.org downloaded versions of python. > > > I confirmed that the Makefile included the line: > > CONFIG_ARGS= '--enable-framework=/Users/{USER}/Library/Frameworks' > '--enable-optimizations' > > (I also tried replacing {USER} with the actual user on my system, 'admin'. > This yielded the same results.) > > I put the external files OpenSSL, tcl/tck, ... (details below) that are > required into the > > .../Universal/other-sources > > directory. I deleted my install of Python3.9 and backed-up and deleted all > the files from > > /usr/local/bin > > Then from > > /Mac/BuildScript > > I ran > > > python3 build-installer.py \ > --universal-archs=intel-64 \ > --dep-target=11 > > Along the way, there were several warnings, but no errors. The end result > is a dmg file: > > python-3.9.8+-macos12-2021-11-10.dmg > > ===================================================================== > > *Issues:* > > 1. I am not sure how to convert the dmg into a "macOS flat installer > package" and would welcome any advice on this point. > > > > You do not need to. All the user needs to do it drag the .app > folder into (typically) /Applications. > > > 2. But in any case, I do not think that an installer based on this dmg > will allow an install in the Library of the user. When I inspect the dmg > file, I find that the post-install scripts include references to the usual > file location in /Library. For example, the script that runs after > installing the framework has the lines: > > PYVER="3.9" > FWK="/Library/Frameworks/Python.framework/Versions/3.9" > > > What post-install script? That's not something that py2app does. > > > The script that runs after installing the files for pip has the lines: > > PYVER="3.9" > PYMAJOR="3" > FWK="/Library/Frameworks/Python.framework/Versions/${PYVER}" > RELFWKBIN="../../..${FWK}/bin" > > This suggests that I have misunderstood the instructions. So I would > appreciate any advice on how to succeed on this path, or suggestions about > alternative paths that might work. In particular, the alternative that > might be feasible would be to use the work from > > https://github.com/codrsquad/portable-python > > This is a recent project, not the one with the same name that was > abandoned that you'll find here: > > https://portablepython.com/ > > > For Barry's Emacs I do 2 steps. > > 1. Build the .app bundle. > 2. Build .dmg that has a bunch of files including the .app bundle. > > There may be a bit too much complexity but have look at how I build the > .app bundle in > > https://github.com/barry-scott/BarrysEmacs/blob/master/Editor/PyQtBEmacs/build-macosx.sh > > and > > https://github.com/barry-scott/BarrysEmacs/blob/master/Editor/PyQtBEmacs/brand.setup-macosx.py > > I'm using PyQt not Tk. > > Barry > > > > > Thanks for reading through all this! > > > ===================================================================== > > PS: Contents of my .../Universal/other-sources directory: > > -rw-r--r-- 1 admin staff 367573 Nov 10 00:53 > ncurses-5.9-20120616-patch.sh.bz2 > -rw-r--r-- 1 admin staff 2826473 Nov 10 00:53 ncurses-5.9.tar.gz > -rw-r--r-- 1 admin staff 9834044 Nov 9 22:19 openssl-1.1.1l.tar.gz > -rw-rw-rw-@ 1 admin staff 2956627 Nov 10 01:06 > sqlite-autoconf-3350500.tar.gz > -rw-rw-rw-@ 1 admin staff 10259009 Nov 9 22:55 tcl8.6.11-src.tar.gz > -rw-rw-rw-@ 1 admin staff 4496914 Nov 10 00:37 tk8.6.11-src.tar.gz > -rw-rw-rw-@ 1 admin staff 1490665 Nov 10 00:45 xz-5.2.3.tar.gz > > ===================================================================== > > > Paul Romer > paul at paulromer.net | paulromer.net | @paulromer > > > _______________________________________________ > Pythonmac-SIG maillist - Pythonmac-SIG at python.org > https://mail.python.org/mailman/listinfo/pythonmac-sig > unsubscribe: https://mail.python.org/mailman/options/Pythonmac-SIG > > > _______________________________________________ > Pythonmac-SIG maillist - Pythonmac-SIG at python.org > https://mail.python.org/mailman/listinfo/pythonmac-sig > unsubscribe: https://mail.python.org/mailman/options/Pythonmac-SIG > -- Christopher Barker, PhD (Chris) Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython -------------- next part -------------- An HTML attachment was scrubbed... URL: