|
| 1 | +--- |
| 2 | +layout: "post" |
| 3 | +title: "PyCharm: Projects & Environments" |
| 4 | +date: 2024-12-03 |
| 5 | +images: "/assets/images/2024-12-03-pycharm-project-envs" |
| 6 | +--- |
| 7 | + |
| 8 | +<script> |
| 9 | +MathJax = { |
| 10 | + tex: { |
| 11 | + inlineMath: [['$', '$'], ['\\(', '\\)']] |
| 12 | + }, |
| 13 | + svg: { |
| 14 | + fontCache: 'global' |
| 15 | + } |
| 16 | +}; |
| 17 | +</script> |
| 18 | +<script type="text/javascript" id="MathJax-script" async |
| 19 | + src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"> |
| 20 | +</script> |
| 21 | + |
| 22 | +I use [PyCharm](https://www.jetbrains.com/pycharm/) for most, if not all, of my development. |
| 23 | +Professional edition at work. |
| 24 | +Community edition everywhere else. |
| 25 | +There are some subtle differences between the two—[project](https://www.jetbrains.com/help/pycharm/setting-up-your-project.html) and [virtual environment](https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html) management aren't one them. |
| 26 | + |
| 27 | +# Projects |
| 28 | +When I first started using PyCharm I worked in a single [repo](https://en.wikipedia.org/wiki/Repository_(version_control)). |
| 29 | +As my responsibilities increased, I was asked to work on others. |
| 30 | +I'd [`git clone`](https://git-scm.com/docs/git-clone) new repos to the same parent directory as my other pre-existing repos |
| 31 | +and work away. |
| 32 | +>What my directory resembled. |
| 33 | +>```text |
| 34 | +>📂 |
| 35 | +>├── 📂 Repo_1 |
| 36 | +>├── 📂 Repo_2 |
| 37 | +>├── ... |
| 38 | +>└── 📂 Repo_N |
| 39 | +> |
| 40 | +>``` |
| 41 | +
|
| 42 | +Over time, I noticed PyCharm was turning into a snail. 🐌 |
| 43 | +Using the terminal. |
| 44 | +Navigating the directory pane. |
| 45 | +Running code via the interpreter. |
| 46 | +It didn't matter what I did, everything was slow. |
| 47 | +
|
| 48 | +I don't remember exactly where I read the suggestion (I'll assume [Stack Overflow](https://stackoverflow.com/questions/tagged/pycharm)), |
| 49 | +but someone mentioned treating each repo as its own PyCharm project. |
| 50 | +In simpler terms, ths meant opening PyCharm at the _repo_ level, i.e., |
| 51 | +```text |
| 52 | +❌ 📂 <- not here |
| 53 | +├── ✅ 📂 Repo_1 <- open PyCharm here, |
| 54 | +├── ✅ 📂 Repo_2 <- here, |
| 55 | +├── ... |
| 56 | +└── ✅ 📂 Repo_N <- or here |
| 57 | +
|
| 58 | +``` |
| 59 | +
|
| 60 | +Doing this reduced the amount of files that PyCharm had to inspect. |
| 61 | +The less work PyCharm has to do, the faster it can run. |
| 62 | +It also means I'm less to prone to looking at the wrong file/folder by accident. |
| 63 | +Ah... |
| 64 | +Modularity. |
| 65 | +🧘 |
| 66 | +>[!NOTE] |
| 67 | +>If you have multiple _small_ repos this may not be an issue. |
| 68 | +>But I still advise considering this approach as it's helped me keep code separate. |
| 69 | +
|
| 70 | +# Environments |
| 71 | +I wrote a [blog post](https://medium.com/@ianiat11/we-recommend-creating-an-environment-da38af0cecbb) a couple years ago |
| 72 | +that briefly covers two kinds of virtual environments: |
| 73 | +[`conda`](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html) and [`venv`](https://docs.python.org/3/library/venv.html). |
| 74 | +If you read it you may notice that I'm not a big fan of `conda`, so we're not going to talk about here. |
| 75 | +Instead we'll use old faithful—`venv` |
| 76 | + |
| 77 | +Managing repos as separate projects is great for modularity. |
| 78 | +Having a dedicated environment for each project may help too. |
| 79 | +Or at least that's what I do. |
| 80 | + |
| 81 | +Let me share a scenario that both myself and at least one of my colleagues has experienced: |
| 82 | +>I have $N$ repos with different requirements—various packages, maybe even different Python versions. |
| 83 | +>To work across different repos I have to switch between the environments. |
| 84 | +>Unfortunately, I sometimes forget that I've activated one repo's environment and install another repo's requirements. |
| 85 | +>This may lead to conflicting package versions, amongst other things. |
| 86 | +>It's pretty easy to reset an environment back to its repo's requirements, but also extremely tedious. |
| 87 | +>How can I keep my environments and repos in-sync? |
| 88 | +> |
| 89 | +>Here is the existing layout: |
| 90 | +>```text |
| 91 | +>📂 |
| 92 | +>├── 🔧 env_1 |
| 93 | +>├── 🔧 env_2 |
| 94 | +>├── ... |
| 95 | +>├── 🔧 env_N |
| 96 | +>├── 📂 Repo_1 |
| 97 | +>├── 📂 Repo_2 |
| 98 | +>├── ... |
| 99 | +>└── 📂 Repo_N |
| 100 | +> |
| 101 | +>``` |
| 102 | +
|
| 103 | +From the get-go we could move the environments to their respective repos. |
| 104 | +```text |
| 105 | +📂 |
| 106 | +├── 📂 Repo_1 |
| 107 | +│ ├── 🔧 env_1 |
| 108 | +│ └── ... |
| 109 | +├── 📂 Repo_2 |
| 110 | +│ ├── 🔧 env_2 |
| 111 | +│ └── ... |
| 112 | +├── ... |
| 113 | +└── 📂 Repo_N |
| 114 | + ├── 🔧 env_N |
| 115 | + └── ... |
| 116 | +
|
| 117 | +``` |
| 118 | +This would add a degree of separation between them as well as allow us to open the repos as PyCharm projects. |
| 119 | +Opening repos as projects keeps us from activating other environments because we won't be able to see them |
| 120 | +(unless you `cd ..` then `ls` 😜). |
| 121 | + |
| 122 | +# Virtual Environments As Interpreters |
| 123 | +My workflow consists of opening a repo as a project, |
| 124 | +then activating the local environment via `git-bash` (or whatever CLI you prefer). |
| 125 | +This does not, however, allow you to run scripts by default. |
| 126 | +To do that you'll need to configure the project's interpreter by pointing it to your local environment. |
| 127 | + |
| 128 | +I believe this is nearly automatic in newer versions of PyCharm, but if you want/need to do it manually, here's how: |
| 129 | +1. Open PyCharm's settings (find the cog symbol ⚙️ and select "settings" or hit the corresponding [hotkey](https://www.jetbrains.com/help/pycharm/mastering-keyboard-shortcuts.html)). |
| 130 | +> |
| 131 | +2. Click "Project: <your project/repo name>" in the left pane |
| 132 | +> |
| 133 | +3. Click "Python Interpreter" |
| 134 | +> |
| 135 | +4. Click "Add Interpreter" in the top right of the window (should be in <span style="color:blue">blue</span>) |
| 136 | +> |
| 137 | +5. Click "Add Local Interpreter..." |
| 138 | +> |
| 139 | +6. Click "Select existing" |
| 140 | +> |
| 141 | +7. Set the Path field to the "python.exe" in your project's environment (should be something like "./env/Scripts/python.exe") |
| 142 | +> |
| 143 | +8. Click "OK" all the way back to the "Python Interpreter" menu. |
| 144 | +> |
| 145 | +9. **BONUS** You can associate this virtual environment to the current project (hiding it when you view settings in other projects) by clicking the interpreter drop-down, selecting "Show All", then selecting the checkbox, "Associate this virtual environment with the current project". |
| 146 | +> |
| 147 | +> |
| 148 | +> |
| 149 | +
|
| 150 | +You should now be able to run python within PyCharm using the ["Run" option](https://www.jetbrains.com/help/pycharm/running-without-any-previous-configuring.html). |
| 151 | + |
| 152 | +# Gotcha |
| 153 | +Setting the project interpreter may lead to a weird quirk in the terminal. |
| 154 | +Here's how to check for it. |
| 155 | +1. Open your prefered CLI within PyCharm (I use `git-bash`). |
| 156 | +2. Activate your environment how you normally would (`source env/Scripts/activate` for `venv` users) |
| 157 | +3. Try to use any bash/CLI commands such as `pwd` or `ls` |
| 158 | + |
| 159 | +If these steps result in an error message like this: |
| 160 | +>```shell |
| 161 | +>$ source env/Scripts/activate |
| 162 | +>bash: cygpath: command not found |
| 163 | +>``` |
| 164 | +
|
| 165 | +or this: |
| 166 | +>```shell |
| 167 | +>$ ls |
| 168 | +bash: ls: command not found |
| 169 | +>``` |
| 170 | +
|
| 171 | +Then you have a terminal setting configured that you'd probably like to unset. |
| 172 | +1. Open the settings window again |
| 173 | +2. Navigate to "Tools" in the left pane |
| 174 | +> |
| 175 | +3. Click "Terminal" |
| 176 | +> |
| 177 | +4. Scroll to the bottom and uncheck "Activate virtualenv" |
| 178 | +> |
| 179 | +5. Click "Apply" |
| 180 | +6. Click "OK" |
| 181 | +7. Restart your terminal |
| 182 | +
|
| 183 | +Voila! Now you can activate your environment from the terminal and still use your other commands. |
| 184 | +
|
| 185 | +If you'd like to persist this setting to every _new_ project your create, you can do so by editing the project settings. |
| 186 | +1. Go to File > New Projects Setup > Settings for New Projects... |
| 187 | +> |
| 188 | +2. Repeat the steps we took to uncheck the "Activate virtualenv" configuration. |
| 189 | +
|
| 190 | +# Accessing Your Other Projects |
| 191 | +I'd like to share one more thing before we part: how to access your other projects. |
| 192 | +
|
| 193 | +We've made our PyCharm workflow a bit more modular |
| 194 | +by treating each repo as its own project and dedicating a virtual environment to it. |
| 195 | +PyCharm makes it easy for us to switch projects without leaving the curernt one. |
| 196 | +
|
| 197 | +At the top left of the window there's the name of our current project: |
| 198 | +> |
| 199 | +
|
| 200 | +This is a drop-down menu. |
| 201 | +Clicking it will show us all of our currently registered projects. |
| 202 | +> |
| 203 | +
|
| 204 | +When we click any of them we're greeted with an option menu: |
| 205 | +> |
| 206 | +
|
| 207 | +- "This Window" will replace your current project with the one you selected. |
| 208 | +>I use this when I'm done working in the current project. |
| 209 | +- "New Window" will open a new PyCharm instance with the project you selected. |
| 210 | +>I use this one if I want to work on two projects at the same time, e.g., one project depends on the other. |
| 211 | +- "Attach" will all you to view both projects within the current PyCharm instance |
| 212 | +>This is similar to what we've been moving away from—one directory to rule them all. |
| 213 | +> I rarely use this option. |
| 214 | +- "Cancel"... you know what that does 😜 |
| 215 | +
|
| 216 | +<script src="https://giscus.app/client.js" |
| 217 | + data-repo="it176131/it176131.github.io" |
| 218 | + data-repo-id="R_kgDOK1ukqg" |
| 219 | + data-category="Announcements" |
| 220 | + data-category-id="DIC_kwDOK1ukqs4CcOnS" |
| 221 | + data-mapping="pathname" |
| 222 | + data-strict="0" |
| 223 | + data-reactions-enabled="1" |
| 224 | + data-emit-metadata="0" |
| 225 | + data-input-position="top" |
| 226 | + data-theme="light" |
| 227 | + data-lang="en" |
| 228 | + data-loading="lazy" |
| 229 | + crossorigin="anonymous" |
| 230 | + async> |
| 231 | +</script> |
0 commit comments