mklement0 / fileicon

macOS CLI for managing custom icons for files and folders

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

macOS 12.3 Beta (21E5196i) removes python 2, breaks app

oschrenk opened this issue · comments

Thank you for the wonderful app. My icons never looked better.

Unfortunately macOS 12.3 Beta removes the system python and therefore the hardcoded /usr/bin/python path will fail.

I changed the line to /usr/local/bin/python3 and did pip3 install pyobjc but I think that version of the Cocoa bindings might not be compatible. I get

<stdin>:4: UninitializedDeallocWarning: leaking an uninitialized object of type NSImage
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
AttributeError: 'str' object has no attribute 'decode'
fileicon: ERROR: ABORTING due to unexpected error.

Ah. .decode('utf-8') was removed in python3 since it's all unicode now. I removed both instances of that and the app now works again.

I guess that means these changes

  1. Getting the right python path (probably defaulting to python3)
  2. Dropping .decode('utf-8')
  3. Changing the homebrew formula to require python3
  4. Document/require to install pip3 install pyobjc

Thanks for bringing this to my attention, and thanks for the nice feedback.

Will future macOS versions not ship with any Python version, or will they ship with Python 3+?

If the latter, can python3 be relied upon (for the foreseeable future)?

If so, in what macOS version did python3 first become available?

Sorry for asking basic questions - it's been a while since I've paid attention to developing on macOS.

You mention pip3 - that suggests the need for a preexisting Python 3 installation.

I don't think Python will ever be bundled into macOS again. They do offer a stub pip3 and python3 under /usr/bin though. Invoking those once will open a dialog inviting the user to install XCode Terminal tools.

I personally use homebrew to install python which is why I mentioned /usr/local/bin

So depending on how you would bundle it, you might get away with just switching out /usr/bin/python with /usr/bin/python3 and rely on macOS to trigger that dialog to install Python 3. But

It will be interesting what solutions the Python/macOS community come up with to offer a consistent experience.

Invoking those once will open a dialog inviting the user to install XCode Terminal tools

.... which will then also install Python 3

@oschrenk, thanks for your detailed analysis and suggestions.

I've updated the npm registry version (and therefore this repo) with v0.3.0, which now tries to use an available python3 in the path if /usr/bin/python is missing.

If so, it performs an on-demand, user-level installation of the necessary pyobjc-* packages (pyobjc-core, pyobjc-framework-Cocoa).

However, I'm unclear on how to update the Homebrew formula (which is still at v0.2.4):

I don't want it to require and therefore automatically install the Homebrew version of Python 3, as that would preempt /usr/bin/python3, which users who've replaced the stub with the Xcode command-line tools-installed version may not want.

But merely updating the current formula to v0.3.0 would break the formula's test command, if no functioning python3 is present on the system.

Any ideas on how to best handle this?

I'll try to read up on it.

So far I found documentation at https://docs.brew.sh/Python-for-Formula-Authors

But it is "slightly outdated" (to be expected at this point) as it mentions the system python.

The formula was updated in core. The tests seem to run fine.

Homebrew/homebrew-core#95002

Intriguing, but good to hear. (Do people have automated workflows for that?)

This is a step in the right direction, but still requires either a previously installed /usr/bin/python3 or a manually installed Homebrew version of Python 3.

Thanks for the link for Python formula authors; much of it is over my head, but adding a simple

depends_on "python@3.10"

to the formula is another step in the right direction, as that automatically installs a private (keg-only) version when brew install fileicon is called, and I can figure out its location at runtime with
"$(brew --prefix)/opt/python@3.10/bin/python3"

However, it would also be nice to perform the on-demand installation of the pyobjc-* packages in a private location.
I'll look into using environment variables for that, but do you know if and how PowerShell's virtual environments could help here?

I have some time on Sunday, I'll look into it.

But as I understand virtualenv is part of the solution

Something like this (untested) might do it

class Fileicon < Formula
  include Language::Python::Virtualenv
  desc "macOS CLI for managing custom icons for files and folders"
  homepage "https://github.com/mklement0/fileicon"
  url "https://github.com/mklement0/fileicon/archive/v0.3.0.tar.gz"
  sha256 "d4835a940bcec7cf5bd4531dab6062b04761d7bcfc328bf2599400b24015d0e2"
  license "MIT"

  bottle do
    sha256 cellar: :any_skip_relocation, all: "351fd94a479c755b17d874a82eba7986842aaeb57e8b6d65c4aee3b1b5434f32"
  end

  depends_on "python@3.10"
  
resource "six" do
    url "https://files.pythonhosted.org/packages/25/31/c63a44292b13ffcb93141192af228a5b71e82d81e80e5d3354fc1c495e72/pyobjc-8.2.tar.gz"
    sha256 "20c8dda07debf6f2ac20fb0eaada82b938aa25ae87e481b047e27b14ee854a04"
  end

  def install
    virtualenv_install_with_resources
    bin.install "bin/fileicon"
    man1.install "man/fileicon.1"
  end

  test do
    icon = test_fixtures "test.png"
    system bin/"fileicon", "set", testpath, icon
    assert_predicate testpath/"Icon\r", :exist?
    stdout = shell_output "#{bin}/fileicon test #{testpath}"
    assert_includes stdout, "HAS custom icon: '#{testpath}'"
  end
end

Hi @mklement0
I have already Python macOS Installer installed on macOS Monterey 12.3 beta 5
Fileicon stuck on that

​Icon-Changer Start
Performing one-time user-level installation of required Python packages: pyobjc-core pyobjc-framework-Cocoa - this can take while...

I am using lates release of fileicon on my app Icon Changer for the test

@oschrenk, thank you for that - I'll take a look too.

@chris1111, are you saying that the on-demand installation of these packages never finishes? (I have seen it take a long time)

@oschrenk, thank you for that - I'll take a look too.

@chris1111, are you saying that the on-demand installation of these packages never finishes? (I have seen it take a long time)

Yea because the progres bar of the App continue and never stop, without changing Icon
I can see and save the Log and that's what it says

It is strange because manually on Terminal it works

Screen Shot 2022-03-02 at 4 38 29 PM

You can achieve this without any python dependency by using the AppleScript-ObjC bridge instead:

    osascript << EndOfScript
        use framework "Cocoa"

        set sourcePath to "$imageSource"
        set destPath to "$target"

        set imageData to (current application's NSImage's alloc()'s initWithContentsOfFile:sourcePath)
        (current application's NSWorkspace's sharedWorkspace()'s setIcon:imageData forFile:destPath options:2)
EndOfScript

The macadamias slack group have a pre-packaged python available at https://github.com/macadmins that a lot of people are using. Other than these 3rd party options you /could/ bundle a version of python, but that's asking a lot I know. :-\

@scriptingosx, thank you very much - that is by far the simplest solution and eliminates all the Python headaches.

I've just published v0.3.1 to the npm registry, which uses AppleScript instead of Python.

Now we just have to wait for the Homebrew elves to update the formula...

@oschrenk, thanks again for your help, too.

@damacguy, thanks for the tip - fortunately, no longer necessary.

@mklement0 it's likely that the macadamias python could already be installed, so the delay in waiting to download another copy (although just once) isn't required if the other version is already there. Or are you checking for python3 existing? Haven't looked for code updates yet...

@damacguy, thanks - I'll definitely keep that in mind for future projects, but with the just-released v0.3.1, fileicon no longer depends on Python, so there's no problem left to solve.

OK, I bit the bullet and became my own Homebrew elf:

The formula has been updated and merged, so you can upgrade to v0.3.1 as follows:

brew update && brew install fileicon