Skip to content

Commit 120486c

Browse files
authored
Merge pull request #70 from it176131/pycharm-envs
Pycharm envs
2 parents cfd0c26 + ce05777 commit 120486c

File tree

18 files changed

+231
-0
lines changed

18 files changed

+231
-0
lines changed
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
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+
>![settings-button]({{ page.images | relative_url }}/settings1.png)
131+
2. Click "Project: <your project/repo name>" in the left pane
132+
>![settings-button]({{ page.images | relative_url }}/settings2.png)
133+
3. Click "Python Interpreter"
134+
>![settings-button]({{ page.images | relative_url }}/settings3.png)
135+
4. Click "Add Interpreter" in the top right of the window (should be in <span style="color:blue">blue</span>)
136+
>![settings-button]({{ page.images | relative_url }}/settings4.png)
137+
5. Click "Add Local Interpreter..."
138+
>![settings-button]({{ page.images | relative_url }}/settings5.png)
139+
6. Click "Select existing"
140+
>![settings-button]({{ page.images | relative_url }}/settings6.png)
141+
7. Set the Path field to the "python.exe" in your project's environment (should be something like "./env/Scripts/python.exe")
142+
>![settings-button]({{ page.images | relative_url }}/settings7.png)
143+
8. Click "OK" all the way back to the "Python Interpreter" menu.
144+
>![settings-button]({{ page.images | relative_url }}/settings8.png)
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+
>![settings-button]({{ page.images | relative_url }}/settings9.png)
147+
>
148+
>![settings-button]({{ page.images | relative_url }}/settings9.5.png)
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+
>![settings-button]({{ page.images | relative_url }}/terminal2.png)
175+
3. Click "Terminal"
176+
>![settings-button]({{ page.images | relative_url }}/terminal3.png)
177+
4. Scroll to the bottom and uncheck "Activate virtualenv"
178+
>![settings-button]({{ page.images | relative_url }}/terminal4.png)
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+
>![settings-button]({{ page.images | relative_url }}/project1.png)
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+
>![settings-button]({{ page.images | relative_url }}/multi1.png)
199+
200+
This is a drop-down menu.
201+
Clicking it will show us all of our currently registered projects.
202+
>![settings-button]({{ page.images | relative_url }}/multi2.png)
203+
204+
When we click any of them we're greeted with an option menu:
205+
>![settings-button]({{ page.images | relative_url }}/multi3.png)
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>
4.64 KB
Loading
54.9 KB
Loading
20.4 KB
Loading
91.7 KB
Loading
12.3 KB
Loading
19.5 KB
Loading
21.6 KB
Loading
3.18 KB
Loading
7.45 KB
Loading

0 commit comments

Comments
 (0)