Doing Python development under Mac OS
peter-whittaker.com
peter-whittaker.com
In addition, I'm not sure tox-pyenv is required. I use tox with multiple pyenv-installed Python versions and have never used it.
Base:
- install homebrew
- brew install openssl readline sqlite3 xz zlib # recommended
- brew install pyenv
- pyenv install <version> # for one or more versions
Project: - create/clone project directory
- cd project directory
- pyenv local x.y.z x.y.z ... # include each version the project supports
- python3 -m venv .venv # create virtualenv for project using one of the pyenv versions
- install the project into the virtualenv
- install any additional dependencies into this virtualenv too, if necessary
Edit: I'd also add that if you do need a tool to be installed globally, it's better to use pipx or pip with --user. It's generally not a good idea to install things into a system-level Python.Tensorflow, cuda, and nvidia were a nightmare that took me 5 days to resolve on ubuntu 18 since it was my first time setting it up ever. There was literally no working guides or people posting with my exact issue, but tons of posts about other people having a nightmare of a time.
In the end I figured out I had to go find this one file/library nvidia had moved around between versions of drivers/cuda even though documentation suggested they hadn't and I was using the versions that were supposed to work fine. In the end, fixing it was either by setting an environment variable because the default path was wrong or editing the path in a config file. I'm not remembering which now.
These days I use languages that don't do this for my daily drivers, it's better for my sanity.
I think Conda is trying too hard to hit the middle ground between full containers (Docker or Singularity) and virtualenv’s. If your program is too complicated to be managed with a venv, it’s better to package it up as a full container and be done with it.
Also, I don’t think Conda would have helped here when the problem is lack of specific Python versions installed at the system level. On a Mac (and everywhere, really), I try my best to avoid the main system Python install and use a user-local (compiled) install when I need a specific version that isn’t available by default.
What?
It seems to me that this awful design choice is root of the problem, and not MacOS at all.
It's not an awful choice, when it's exactly what you want to do. The dependency is that tox will run the tests against a Python 3.6 target environment and a Python 3.8 target environment.
The dual requirement is asking for test assurance that Yamale will work with 3.6 or 3.8.
MacPorts is slower, but offers peace of mind -- 'cause when I'm trying to develop something, the last thing I want to worry about is dependency issues (gross)
1. Install Docker CE on the Mac.
2. Start a container for your work, e.g.,
docker run python:3.8
3. When you need to get back into it, use docker exec -it <first_three_container_characters> ipython
4. If the container is shut down from a reboot or something, start it with docker start <first_three_container_characters>
What's really cool about this is `bash` can be run instead of `ipython` to get a Bash prompt and install any Linux dependency. In theory, at some point if one project has conflicting dependencies with another project a new container can be spun up, but this is not something that's come up in practice yet.This has worked so well for me these past few months, I actually replicated it on my Linux computer. I took a few extra convenience steps like mounting `/home/` and aliasing `ipython` to a command that starts the container before executing the command, but other than that it's been a pretty seamless experience and I never have to worry about OS-level Python installation stuff any more. I use a scipy image with Jupyter Lab in a similar way for my graphical notebook needs.
The only time I would recommend against this is when performance is an issue (like training ML models), but at work we use AWS machines with their own Docker environments for that. For everything else, Mac, Linux or maybe even Windows, Docker is the only way I now recommend firing up Python.
I appreciate Docker's approach, but it's definitely a bit of a nuclear option (at least on non-Linux systems).
With poetry I can `poetry add foo` and `foo` will be added as a dependency and importantly all its dependencies will be locked in the `poetry.lock` file.
With Nix either you write all your definitions from scratch, which feels like maintaining a lock file by hand, or you specify a package like `numpy` in your dependencies that is defined in the nix packages and hope that the next time you update nix packages nothing breaks.
Also if you want a package that isn't in nix packages you have to write the definition yourself, which isn't a big deal if you start a project off with nix and gradually add dependencies as you need them, but if you are trying to migrate your project with 200+ dependencies it feels really tedious.
My python projects usually rely almost entirely on the same 3 or 4 already downloaded libraries, plus the large stdlib. They run 3.8. That experience is not comparable, and not in favour of Rust. Maybe it's because I don't use whatever Tox is, but I don't. So no. Not beginner friendly.
1. Install pyenv [1] and the specific version you plan to use.
2. Use poetry [2] for dependency management, which pins the python version to the one defined, ideally the one you've set via pyenv.
--
I think the author is doing the best they can considering all of these tools and resources aren't updated to this pattern yet, but I'd hate to see this become the new normal for any developer entering into the field. What a way to scare off new dev friends!
Really facinating. I think things like go / rust etc? may work better - you compile everything and compile to binary on platform, so don't need to build and carry around environments everywhere.
I moved to docker deploys / dockerfiles locally for pretty much everything. Totally overkill, but when I switched to working from home was so glad I could just get up and go without getting my overall system sorted out.
I haven't totally figured out the WSL2 python remote interpreter / debugger code flow yet however, so still using docker. I'm sure WSL2 will or is an option.
I've been tempted to just vnc or similar into a cloud instance, but my local machine is to fast by comparison for the price.
My mac is a couple years old and I don't have the fan of death problem everyone seems to complain about. The best thing is allowing my team to know with confidence we're developing against the exact same environment.