<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PyCharm : The only Python IDE you need. | The JetBrains Blog</title>
	<atom:link href="https://blog.jetbrains.com/pycharm/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.jetbrains.com</link>
	<description>Developer Tools for Professionals and Teams</description>
	<lastBuildDate>Wed, 16 Sep 2026 15:20:32 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://blog.jetbrains.com/wp-content/uploads/2026/09/icon-512.webp</url>
	<title>PyCharm : The only Python IDE you need. | The JetBrains Blog</title>
	<link>https://blog.jetbrains.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Behind the Scenes: How the OpenTelemetry Plugin Maps Your Microservices in Real-Time</title>
		<link>https://blog.jetbrains.com/platform/2026/09/how-to-service-map-with-opentelemetry/</link>
		
		<dc:creator><![CDATA[Nikita Dukin]]></dc:creator>
		<pubDate>Wed, 16 Sep 2026 12:34:47 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/09/JB-social-BlogFeatured-1280x720-1-3.png</featuredImage>		<product ><![CDATA[go]]></product>
		<product ><![CDATA[pycharm]]></product>
		<product ><![CDATA[research]]></product>
		<product ><![CDATA[webstorm]]></product>
		<category><![CDATA[all-things-web]]></category>
		<category><![CDATA[backstage]]></category>
		<category><![CDATA[plugin-development]]></category>
		<category><![CDATA[goland]]></category>
		<category><![CDATA[idea]]></category>
		<category><![CDATA[intellij-platform]]></category>
		<category><![CDATA[plugin-highlights]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[pycharm]]></category>
		<category><![CDATA[research]]></category>
		<category><![CDATA[rider]]></category>
		<category><![CDATA[webstorm]]></category>
		<category><![CDATA[intellij-idea]]></category>
		<category><![CDATA[opentelemetry]]></category>
		<category><![CDATA[performance-optimization]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=platform&#038;p=740440</guid>

					<description><![CDATA[We’ve all been there: you join a new project, and the first thing you ask for is the architecture diagram. You&#8217;re handed a diagram that looks great, but after a week of debugging, you realize it’s six months out of date. Service A hasn&#8217;t talked to Service B since the spring, and there’s a new [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>We’ve all been there: you join a new project, and the first thing you ask for is the architecture diagram. You&#8217;re handed a diagram that looks great, but after a week of debugging, you realize it’s six months out of date. Service A hasn&#8217;t talked to Service B since the spring, and there’s a new message queue nobody bothered to document.</p>



<p>Figuring out how a complex system <em>actually</em> fits together is a classic engineering headache. You can try to figure it out manually (if you have faith in yourself and enough time to spare), or you can use static analysis to explore the codebase (which often fails to capture how services are actually wired together at runtime).</p>



<p>But there’s a third way: <strong>dynamic analysis</strong>. What if we could just watch the system run and draw the map based on what is actually happening?</p>



<p>Since the OpenTelemetry plugin is already collecting a wealth of runtime data – logs, metrics, and traces – we realized we had the perfect opportunity to auto-generate this architecture map for you. Here’s a look under the hood at the Service Map feature, built as part of a collaboration between the Rider Execution team and <a href="https://lp.jetbrains.com/research/software-engineering/" target="_blank" rel="noopener">Software Engineering Research</a>.</p>



<h2 class="wp-block-heading">The magic ingredient: traces</h2>



<p>If you’re familiar with observability, you know the &#8220;three pillars&#8221;: logs, metrics, and traces.</p>



<p>While logs tell you <em>what</em> happened and metrics tell you <em>how much</em>, <strong>traces</strong> show you the <em>journey</em> of a request through your system. Traces are made up of individual units of work called <strong>spans</strong>.</p>



<p>Because OpenTelemetry standardizes these spans (for instance, explicitly defining <a href="https://opentelemetry.io/docs/specs/semconv/http/http-spans/#http-client-span" target="_blank" rel="noopener">HTTP Client</a> and <a href="https://opentelemetry.io/docs/specs/semconv/http/http-spans/#http-server" target="_blank" rel="noopener">HTTP Server</a> spans), they are the ultimate cheat code for understanding system architecture. Relying on the OpenTelemetry standard means the plugin can visualize your system completely independently of your technology stack, as long as your app and libraries emit spans the way OTel expects.</p>



<p>Building a map from traces has one massive advantage: it&#8217;s the source of runtime truth. We aren&#8217;t guessing based on source code or outdated specs. We are looking at data generated by the live system.</p>



<h2 class="wp-block-heading">How it works</h2>



<p>So, how does this actually work inside your JetBrains IDE?</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" fetchpriority="high" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/09/image3.png" alt="" class="wp-image-740475"/></figure>



<p>When you start your IDE with OpenTelemetry plugin enabled, the plugin starts a lightweight local OpenTelemetry backend that can process your application telemetry data.&nbsp;</p>



<p>When you hit <em>Run</em> in your IDE:&nbsp;</p>



<ol class="wp-block-list">
<li>Plugin provides standard OTel environment variables to the application, so it knows that data should be sent to the local backend.</li>



<li>Your app (already configured to emit spans) starts sending telemetry data to our local backend.</li>



<li>The backend asynchronously crunches these incoming spans, continuously building and updating an internal model of your architecture.</li>



<li>When you click on the <em>Service Map</em> tab, the OpenTelemetry plugin fetches the latest structural model from the backend and renders the visual diagram.</li>
</ol>



<h2 class="wp-block-heading">The messy reality of telemetry data</h2>



<p>If you look at an architecture diagram, it looks static and orderly. But the stream of telemetry data generating that diagram is anything but. Before we could write an algorithm to connect the dots, we had to solve a few hidden challenges:</p>



<h3 class="wp-block-heading">Chaos in the wire&nbsp;</h3>



<p>Spans arrive completely independently, and their order is never guaranteed. A parent span might finish and arrive <em>after</em> its child span has already been processed.</p>



<h3 class="wp-block-heading">No finish line&nbsp;</h3>



<p>A trace never explicitly says &#8220;I&#8217;m done.&#8221; At any given moment, we can never be 100% sure that a late-arriving span isn&#8217;t about to show up.</p>



<h3 class="wp-block-heading">Untyped payloads</h3>



<p>OpenTelemetry doesn’t provide a strictly typed version for each span type. Instead, each span carries a key-value map with attributes that describe the semantics of the operation. We had to deduce what kind of interaction they represent purely by inspecting their attributes.</p>



<h2 class="wp-block-heading">The reconstruction algorithm</h2>



<p>To handle this asynchronous, out-of-order data, we built the architecture reconstruction as a stream processing algorithm. Instead of waiting around for a complete trace – which, as we just established, is impossible to guarantee – we process every span the moment it arrives.</p>



<p>First we figure out what we&#8217;re looking at. We pull the basic metadata off the span, then inspect its semantic attributes to classify it: attributes such as <code>http.request.method</code> and <code>http.response.status_code</code> tell us it&#8217;s an HTTP call, while others point to a database query, a message queue interaction, and so on.</p>



<p>Next we ask which service emitted it. New service we haven&#8217;t seen? It goes on the map. Already there? We merge the new data in and update its statistics.</p>



<p>Then comes the interesting part: connecting the dots across service boundaries. A fully instrumented HTTP call has two sides: the calling service emits a CLIENT span, while the receiving service emits a SERVER span. The trace context travels with the request, so the downstream SERVER span is created as a child of the upstream CLIENT span.</p>



<p>So when an outgoing HTTP Client span shows up, we go looking for its child on the server side. When an incoming HTTP Server span shows up, we look for the parent that called it. If the partner span is already in our system, we draw (or update) the connection between the two services right away. If it isn&#8217;t, we park the span in memory and wait for its other half to arrive.&nbsp;</p>



<p>Other kinds of dependencies require slightly different rules. A database call is usually represented by a single CLIENT span, so we infer the database node directly from its semantic attributes. Messaging is more varied: producer and consumer operations may be connected through a parent-child relationship or through span links, depending on the messaging system and instrumentation. In every case, the backend processes spans as they arrive and incrementally enriches the map as more evidence becomes available</p>



<p>That last step is what lets the plugin build an accurate, real-time map, even when the network delivers everything late and out of order.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/09/image2.png" alt="" class="wp-image-740486"/><figcaption class="wp-element-caption"><em>Service map showing cross-service http communication and db access.<br></em></figcaption></figure>



<p>This way we can process and show you information about http requests, database requests and message queues.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/09/image1.png" alt="" class="wp-image-740497"/><figcaption class="wp-element-caption"><em>Service map showing cross-service communication through message queue (rabbit) and db access.</em></figcaption></figure>



<p>Because the map is built from standard OpenTelemetry spans and the reconstruction algorithm relies on semantic conventions rather than framework-specific APIs, the feature is language- and vendor-agnostic. The same logic works across JVM, .NET, Python, Go, and other OpenTelemetry-instrumented applications, as long as their instrumentation emits the expected spans and propagates context correctly. This also means you can use the feature in the JetBrains IDE that best fits your stack, including IntelliJ IDEA, GoLand, PyCharm, WebStorm, and Rider.</p>



<h2 class="wp-block-heading">See your own architecture</h2>



<p>Want to see your own architecture mapped out in real-time? Expected one HTTP call or database query, but the diagram shows several? Finding that during development gives you time to fix it before release.</p>



<p>You can install the OpenTelemetry plugin right now and stop guessing how your services talk to each other.</p>


    <div class="buttons">
        <div class="buttons__row">
                                                <a href="https://plugins.jetbrains.com/plugin/27488-opentelemetry" class="btn" target="_blank" rel="noopener">Download the OpenTelemetry plugin</a>
                                                    </div>
    </div>







<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Fine-Tuning SOTA Object Detection Models on Real-World Datasets</title>
		<link>https://blog.jetbrains.com/pycharm/2026/08/fine-tuning-sota-object-detection-models-on-real-world-datasets/</link>
		
		<dc:creator><![CDATA[Arina Belova]]></dc:creator>
		<pubDate>Mon, 31 Aug 2026 13:50:29 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/08/PC-social-BlogFeatured-1280x720-1-2.png</featuredImage>		<category><![CDATA[data-science]]></category>
		<category><![CDATA[object-detection]]></category>
		<category><![CDATA[yolo]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=pycharm&#038;p=732973</guid>

					<description><![CDATA[In our previous blog post in this series, we discussed state-of-the-art models for object detection: the architectures, the theory, and what makes YOLO12, YOLO26, and RF-DETR tick. If you want the theoretical background on these models, start there. This post is the practical follow-up: how to actually use these models, how to fine-tune them on [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>In our <a href="https://blog.jetbrains.com/pycharm/2026/07/best-object-detection-models-for-machine-learning-in-2026/">previous blog post</a> in this series, we discussed state-of-the-art models for object detection: the architectures, the theory, and what makes YOLO12, YOLO26, and RF-DETR tick. If you want the theoretical background on these models, start there.</p>



<p>This post is the practical follow-up: how to actually <strong>use</strong> these models, how to <strong>fine-tune</strong> them on diverse, specialized datasets that look nothing like their training data, and how to <strong>evaluate</strong> the results – all within PyCharm.</p>



<h2 class="wp-block-heading">Why fine-tune at all?</h2>



<p>Every pretrained detector you download was trained on some distribution of images, almost always <a href="https://cocodataset.org/" target="_blank" rel="noopener">COCO</a>, which is ~118k training images of everyday scenes containing 80 common object categories (people, cars, dogs, chairs, etc.).</p>



<p>Real-world deployment data rarely looks like COCO. Things that object detection might actually be applied to, such as damaged industrial cables, bone fractures on X-rays, or densely stacked soda bottles on a shelf, are:</p>



<ul class="wp-block-list">
<li><strong>Out of vocabulary</strong>: &#8220;Bone fracture&#8221; is not one of COCO&#8217;s 80 classes, so the model literally has no output category for it.</li>



<li><strong>Out of visual distribution</strong>: X-ray imagery, industrial close-ups, and heavily occluded shelf scenes differ drastically from consumer photos in texture, viewpoint, and object density.</li>
</ul>



<p>Deploying a detector on off-distribution data therefore requires <strong>fine-tuning</strong>. But before we break the models, let&#8217;s establish that we get similar results on our hardware to the ones reported by developers.</p>



<h2 class="wp-block-heading">The models</h2>



<p>For the purposes of this experiment, we’ll focus on three current SOTA object detection families and examine two sizes of each model:</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th><strong>Family</strong></th><th><strong>Variants</strong></th><th><strong>Implementation</strong></th></tr></thead><tbody><tr><td>YOLO12</td><td><code>yolov12n, yolov12m</code></td><td><a href="https://github.com/sunsmarterjie/yolov12" target="_blank" rel="noopener">Original authors&#8217; repo</a></td></tr><tr><td>YOLO26</td><td><code>yolo26n, yolo26m</code></td><td><a href="https://github.com/ultralytics/ultralytics" target="_blank" rel="noopener">Ultralytics</a> PyPI package</td></tr><tr><td>RF-DETR</td><td><code>RFDETRNano, RFDETRBase</code></td><td><a href="https://github.com/roboflow/rf-detr" target="_blank" rel="noopener">Roboflow</a> PyPI package</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">Sanity check: Reproducing COCO <code>val2017</code> baselines</h3>



<p>We’re going to be working with six pretrained checkpoints: Two different sizes of each of the three models. To check that these models are behaving as expected, we evaluated all of them on the full 5,000-image COCO validation dataset (<code>val2017</code>) to verify the numbers reported in the previous post:</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th><strong>Model</strong></th><th><strong>Params (M)</strong></th><th><strong>mAP50</strong></th><th><strong>mAP50-95</strong></th><th><strong>Latency (ms)</strong></th></tr></thead><tbody><tr><td>YOLOv12-N</td><td>2.55</td><td>0.5548</td><td>0.4021</td><td>23.9</td></tr><tr><td>YOLO26-N</td><td>2.57</td><td>0.5498</td><td>0.3952</td><td><strong>12.3</strong></td></tr><tr><td>YOLOv12-M</td><td>19.67</td><td>0.6953</td><td><strong>0.5259</strong></td><td>72.4</td></tr><tr><td>YOLO26-M</td><td>21.90</td><td>0.6906</td><td>0.5181</td><td>13.9</td></tr><tr><td>RF-DETR Nano</td><td>30.47</td><td>0.6750</td><td>0.4835</td><td><strong>12.4</strong></td></tr><tr><td>RF-DETR Base</td><td>32.17</td><td>0.7210</td><td><strong>0.5325</strong></td><td>12.9</td></tr></tbody></table></figure>



<p>Three things stand out even before we leave COCO behind:</p>



<ol class="wp-block-list">
<li><strong>Larger models (mostly) have better performance.</strong> RF-DETR Base leads (0.5325 mAP50-95), but the medium YOLOs get remarkably close (0.5259 / 0.5181) with ~10M fewer parameters.</li>



<li><strong>YOLO26&#8217;s NMS-free design pays off in throughput.</strong> YOLO26-N is the fastest model in the lineup (12.3 ms latency) at essentially the same mAP50-95 as YOLOv12-N, which, despite being the smallest model here, is considerably slower (23.9 ms latency). Attention is expensive. (If you want more detail on the model architectures and how they affect performance, see the <a href="https://blog.jetbrains.com/pycharm/2026/07/best-object-detection-models-for-machine-learning-in-2026/">previous blog post</a> in this series.)</li>



<li><strong>RF-DETR Nano is not &#8220;nano&#8221; by parameter count</strong> (~30M – more than YOLO26-M), but it is well-optimized: With 12.4 ms latency, it is the second-fastest overall.</li>
</ol>



<p>Published papers report <em>optimized</em> inference latency: That is, they measure the model&#8217;s forward pass in isolation, stripped of the surrounding stages of the object detection pipeline. We deliberately skipped that aggressive optimization so our numbers reflect what you&#8217;d actually see when deploying these models.</p>



<p>As a result, our latency figures don&#8217;t line up with the benchmarks in the models&#8217; white papers. There are two main reasons for this:</p>



<ul class="wp-block-list">
<li><strong>Hardware:</strong> We used different hardware from the NVIDIA T4 GPU that serves as the <em>de facto</em> standard in object detection benchmarking.</li>



<li><strong>Unoptimized computation graph:</strong> We ran the models in their native framework rather than converting them to TensorRT. TensorRT compiles a network into a hardware-specific engine, fusing layers, selecting the fastest kernels for the target GPU, and optionally running in reduced precision. That can cut latency substantially, but the resulting engine is tied to one GPU and requires an extra build step, so it doesn&#8217;t represent how these models perform out of the box.</li>
</ul>



<p>Accuracy is a different story: While our latencies diverge from the published ones, our mAP50-95 results fall within reasonable noise bounds of the reported figures.</p>



<p>Now that we’ve seen what our pretrained models can do on COCO, the dataset they were trained on, let&#8217;s see what happens when they&#8217;re tested off distribution.</p>



<h2 class="wp-block-heading">The datasets</h2>



<p>For evaluation, we used <a href="https://rf100-vl.org/" target="_blank" rel="noopener">RF100-VL</a>, a large-scale collection of 100 multimodal datasets covering concepts deliberately chosen to be rare in object detection models’ pretraining data. These datasets contain exactly the off-distribution targets we care about. These targets also mirror common real-life applications for object detection, giving us a realistic test of these models’ capabilities out in the wild.</p>



<p>We picked three datasets that stress test the models in different ways:</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th><strong>Dataset</strong></th><th><strong>Domain</strong></th><th><strong>Why it&#8217;s hard</strong></th><th><strong>Classes</strong></th></tr></thead><tbody><tr><td><strong><code>cable-damage</code></strong></td><td>Technical/industrial</td><td>Fine-grained damage types on visually similar backgrounds</td><td><code>break, thunderbolt</code></td></tr><tr><td><strong><code>bone-fracture</code></strong></td><td>Medical (X-ray)</td><td>Entirely different imaging modality; subtle features</td><td><code>angle, fracture, line, messed_up_angle</code></td></tr><tr><td><strong><code>soda-bottles</code></strong></td><td>Retail</td><td>Heavy occlusion, many near-identical instances per image</td><td><code>coca-cola, fanta, sprite</code></td></tr></tbody></table></figure>



<h2 class="wp-block-heading">Tutorial: Fine-tuning all three models in PyCharm 🙂</h2>



<h3 class="wp-block-heading">Step 1: Setting up the project</h3>



<p>One of the first challenges we had to overcome in this project was that the three implementations do <strong>not</strong> share a compatible set of dependencies. In particular, the two different generations of YOLO require different versions of the <code>ultralytics</code> package. PyCharm offers a clean solution for this: one PyCharm project with three isolated <code>uv</code> environments – one per model family.</p>



<p>We&#8217;ll run our computations on a remote GPU. Configuring a remote interpreter in PyCharm follows the same workflow as a local one: the same dialog and the same dropdown as in the local case. Note that remote interpreters require PyCharm Professional; Community Edition supports local environments only.</p>



<p>Firstly, we need to instantiate our three <code>uv</code> virtual environments via:<br></p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">cd yolov12 &amp;&amp; uv venv .venv --python 3.11 

cd yolov26 &amp;&amp; uv venv .venv --python 3.11 

cd rf-detr &amp;&amp; uv venv .venv --python 3.11</pre>



<p>Once your uv virtual environments exist, register each one as an existing interpreter. Go to <em>Settings | Python | Interpreter</em>, click <em>Add Interpreter → Add Local Interpreter</em>, choose <em>Environment </em>as <em>Select existing</em>, and point the interpreter field at that environment&#8217;s <code>bin/python</code>. PyCharm doesn&#8217;t create anything here, it just picks up the environment <code>uv</code> already built.</p>



<p>Repeat for each environment. From then on, switching is a matter of picking one from the <em>Settings | Python | Interpreter</em> dropdown, or from the interpreter widget in the bottom-right-hand status bar.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/uv_virtual_env.png" alt="" class="wp-image-733186"/></figure>



<p>You can find the full list of dependencies required for each model in their respective project repositories. You can either install all the projects’ dependencies in PyCharm’s built-in <em>Terminal</em> tool window or install individual packages using the<em> Python Packages</em> tool window (including selecting specific versions of packages). You can access both of these tool windows by clicking the relevant icons in the lower left-hand corner of the PyCharm toolbar.&nbsp;</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/Screenshot-2026-08-14-at-16.29.31-1.png" alt="" class="wp-image-733197"/></figure>



<p>For a step-by-step guide on setting up the environments for all three models, see our <a href="https://github.com/ArinaBelova/sota-object-detection-tutorial/blob/main/environments_setup.md" target="_blank" rel="noopener">GitHub implementation</a> of this tutorial.</p>



<h3 class="wp-block-heading">Step 2: Getting the datasets</h3>



<p>To obtain the out-of-COCO-distribution datasets, we can install our datasets via the <code>rf-detr</code> virtual environment, since it has <code>roboflow</code> as one of its core dependencies. We then set the Roboflow API key as an environment variable so that it is available to the API when downloading the datasets.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="shell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pip install roboflow

export ROBOFLOW_API_KEY="your_key_here" # you can get API key here: https://docs.roboflow.com/reference/authentication/authentication/find-your-roboflow-api-key </pre>



<p>After setting everything up, now you can run the Python script below to get the three datasets we’re going to use in our tutorial:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import os
from roboflow import Roboflow

api_key = os.environ.get("ROBOFLOW_API_KEY")

if not api_key:
    raise RuntimeError("ROBOFLOW_API_KEY is not set")

DATASETS = [
    "bone-fracture-7fylg",
    "cable-damage",
    "soda-bottles",
]

VERSION = 2          # RF100 projects are generally published at version 2
FORMAT = "yolov8"    # or "coco", "voc", "yolov5"
rf = Roboflow(api_key=api_key)
workspace = rf.workspace("rf100")

for slug in DATASETS:
    print(f"Downloading {slug} ...")

    try:
        project = workspace.project(slug)
        dataset = project.version(VERSION).download(FORMAT)
        print(f"  -> {dataset.location}")

    except Exception as e:
        print(f"  !! failed: {e}")</pre>



<p>This script connects to the Roboflow cloud service via its Python API client and downloads three specified RF100 datasets in YOLOv8 format. It loops through each dataset, reports where successful downloads are saved, and prints an error if any download fails.</p>



<h3 class="wp-block-heading">Step 3: Getting a zero-shot baseline by using pretrained models on custom data</h3>



<p>Before fine-tuning, we’re going to evaluate the COCO-pretrained checkpoints directly on our three datasets, to see whether the fine-tuning is actually necessary. The result was unambiguous: <strong>The models predicted essentially nothing.</strong></p>



<p><em>Zero-shot mAP50-95 on the test splits of our three datasets:</em></p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th><strong>Model</strong></th><th><strong><code>cable-damage</code></strong></th><th><strong><code>bone-fracture</code></strong></th><th><strong><code>soda-bottles</code></strong></th></tr></thead><tbody><tr><td>RF-DETR Nano</td><td>0.0004</td><td>0.0000</td><td>0.0027</td></tr><tr><td>RF-DETR Base</td><td>0.0005</td><td>0.0000</td><td>0.0004</td></tr><tr><td>YOLOv12-N</td><td>0.0007</td><td>0.0000</td><td>0.0266</td></tr><tr><td>YOLO26-N</td><td>0.0000</td><td>0.0000</td><td>0.0033</td></tr><tr><td>YOLOv12-M</td><td>0.0000</td><td>0.0000</td><td>0.0160</td></tr><tr><td>YOLO26-M</td><td>0.0000</td><td>0.0000</td><td>0.0012</td></tr></tbody></table></figure>



<p>This is to be expected; it’s not a bug! As the models are closed-vocabulary detectors, that is, they have a finite number of predefined target classes, they physically cannot output a class like <code>fracture</code> that isn&#8217;t in their 80-class COCO head.&nbsp;</p>



<p>This is the punchline of this whole post: A model scoring 0.72 mAP50 on COCO scores 0.00 on bone fractures. Pretrained ≠ deployable, even when the model is state of the art. Basic machine learning principles still apply, even in the age of AI!</p>



<h3 class="wp-block-heading">Step 4: Fine-tuning</h3>



<p>All models were fine-tuned on a single <strong>A100 GPU</strong> for <strong>10 epochs</strong>. We used standard Ultralytics/RF-DETR fine-tuning pipelines in order to fine-tune the models on our three datasets. We fine-tuned a model for each dataset. The full fine-tuning pipeline can be found in <code>finetune_rf100.py</code> scripts in the project repo, under the folders for each model.</p>



<p>You can see the core of the training setup below. Both YOLO and RF-DETR are built on PyTorch under the hood, but the training loops are abstracted behind higher-level library APIs: Ultralytics’ <code>YOLO.train()</code> for the YOLO models, and RF-DETR’s own <code>train()</code> functionality.</p>



<h4 class="wp-block-heading">YOLO12 and YOLO26</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">train_model = YOLO(args.model)

train_res = train_model.train(
                data=str(yaml_path),
                epochs=args.epochs,
                imgsz=args.imgsz,
                batch=args.batch,
                device=args.device,
                project=args.project,
                name=run_name,
                exist_ok=True,
                verbose=False,
            )</pre>



<h4 class="wp-block-heading">RF-DETR</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">ModelClass().train(
                dataset_dir=str(coco_dir),
                output_dir=str(output_dir),
                epochs=args.epochs,
                batch_size=args.batch_size,
                grad_accum_steps=args.grad_accum,
                lr=args.lr,
                resolution=resolution,
                early_stopping=True,
                checkpoint_interval=1,
            )</pre>



<h3 class="wp-block-heading">Step 5: Results</h3>



<p>Fine-tuning transforms the picture. You can see the results on the test set after training:</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/accuracy_vs_speed.png" alt="" class="wp-image-733209"/></figure>



<p>On the left, we have the pretrained models’ results for the COCO validation dataset. As we showed earlier, accuracy (mAP50-95) fell between 0.39 and 0.53, and all models except for YOLOv12-M showed low latency. The fine-tuned models on the right showed a similar range of accuracy for the <code>cable-damage</code> and <code>soda-bottle</code> detection tasks, only falling lower for the <code>bone-fracture</code> task. Moreover, the fine-tuned models were comparable in latency to the pretrained models for their intended tasks, and for YOLOv12-M, they were even faster. This suggests that, after fine-tuning to the target domain, the models achieve performance that’s broadly comparable to the pretrained performance on their original training domain.</p>



<p>Let’s now have a closer look at the fine-tuned models’ performance, breaking it down by mAP50 and mAP50-95 for the three separate RF-100 datasets:</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th><strong>Model</strong></th><th><strong><code>cable-damage</code></strong></th><th><strong><code>bone-fracture</code></strong></th><th><strong><code>soda-bottles</code></strong></th></tr></thead><tbody><tr><td>RF-DETR Nano</td><td>0.9195 (0.4391)</td><td>0.2317 (0.1136)</td><td>0.9617 (0.6223)</td></tr><tr><td>RF-DETR Base</td><td><strong>0.9281</strong> (<strong>0.4456</strong>)</td><td><strong>0.4474</strong> (<strong>0.1915</strong>)</td><td>0.9688 (0.6332)</td></tr><tr><td>YOLOv12-N</td><td>0.9236 (0.4378)</td><td>0.0911 (0.0532)</td><td>0.9677 (0.6343)</td></tr><tr><td>YOLO26-N</td><td>0.8165 (0.3681)</td><td>0.0193 (0.0064)</td><td>0.9148 (0.5896)</td></tr><tr><td>YOLOv12-M</td><td>0.8266 (0.3649)</td><td>0.1500 (0.0635)</td><td><strong>0.9706</strong> (<strong>0.6422</strong>)</td></tr><tr><td>YOLO26-M</td><td>0.8707 (0.3896)</td><td>0.2194 (0.1038)</td><td>0.9596 (0.6304)</td></tr></tbody></table></figure>



<p>What the numbers say:</p>



<ul class="wp-block-list">
<li><strong>The <code>soda-bottles</code> target is the easy win.</strong> Every model lands in the 0.91–0.97 mAP50 band. This is likely due to the fact that the domain (consumer products in photos) is visually close to existing classes in COCO, so only the vocabulary was new. Interestingly, the attention model family does great here, with YOLOv12-M taking the top spot (0.6422 mAP50-95).</li>



<li><strong><code>cable-damage</code>: Detection is easy, but localization is hard.</strong> mAP50 reaches 0.93, but mAP50-95 tops out at 0.446. It appears that the models find the damage reliably, yet they struggle to box thin, elongated defects precisely. If your application needs tight boxes at high IoU, this gap would be a significant issue.</li>



<li><strong><code>bone-fracture</code> remains genuinely hard.</strong> The best model (RF-DETR Base, 0.447 mAP50) is far from production-ready, and the performance spread across models is huge. The modality shift from photos to X-rays means the pretrained backbone features transfer poorly. The different image modality and small, sometimes almost indistinguishable bone fractures make the detection task way harder than the one employed on common objects identification. This is the dataset that would most benefit from domain-specific pretraining, more data, or longer fine-tuning.&nbsp;</li>



<li><strong>RF-DETR Base is the most consistent performer</strong>, winning on two out of three datasets and challenging seriously for the third. The DETR-style architecture seems to transfer more robustly to unfamiliar domains.&nbsp;</li>
</ul>



<h3 class="wp-block-heading">Qualitative results</h3>



<p>To visually assess how these models perform, we can overlay the predicted bounding boxes on the images. Let&#8217;s look at the objects our models detected in six random images per class:</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/cable-damage_very_low_res.png" alt="" class="wp-image-733331"/></figure>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/bone-fracture-7fylg.png" alt="" class="wp-image-733256"/></figure>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/soda-bottles_very_low_res.png" alt="" class="wp-image-733320"/></figure>



<p>We can see this confirms the accuracy values we saw above: The noisy images of soda bottles in fridges are labeled accurately, with tight bounding boxes for each object. The cable damage is identified less consistently, with some models failing to find the damage altogether, and others creating unnecessarily large bounding boxes. Finally, the images of broken bones contrast sharply with the other two, with less than half of the images having any break identified, and different models identifying different potential breakage points.</p>



<h2 class="wp-block-heading">Conclusions&nbsp;</h2>



<p>Pretrained object detectors are powerful, based on advancements in model architecture over the past five years, but as we’ve seen here, pretrained does not necessarily mean deployable. All six models performed well on COCO, yet when we applied those same checkpoints directly to our specialized datasets, their performance fell close to zero. However, fine-tuning completely changed that picture.</p>



<p>After only 10 epochs of fine-tuning, all three model families were able to adapt well to both the <code>cable-damage</code> and <code>soda-bottle</code> datasets. As we noted, the <code>soda-bottle</code> task was particularly transferable, likely because it contained objects similar to those contained in COCO. <code>cable-damage</code> was also detected relatively reliably, although the larger gap between mAP50 and mAP50-95 showed that precisely locating these tiny defects was still challenging for all of the models. However, <code>bone-fracture</code> was a completely different story, likely because moving from the sort of natural images contained in COCO to X-rays is a much larger domain shift. While RF-DETR handled this jump best, even its performance shows the limits of fine-tuning, and there are times when you might need to consider more data, longer training, or even domain-specific pretraining.</p>



<p>The broader takeaway is that there is no single “best” detector: It is dependent on the task. Model size, latency requirements, licensing restrictions, and most importantly, the similarity between the model’s pretraining data and your target domain all affect the outcome. It is important to refrain from unquestioningly trusting the numbers reported by model providers and explore the fit of a specific model for your own particular task.</p>



<h2 class="wp-block-heading">Get started with PyCharm today</h2>



<p>In this post, we’ve gone from validating pretrained YOLO12, YOLO26, and RF-DETR checkpoints on COCO to testing them zero-shot on specialized data, to fine-tuning them on three very different object detection tasks, and then finally, comparing the resulting accuracy and latency. Along the way, we’ve seen how PyCharm can help manage the practical side of a project like this, where multiple model families require different dependency sets and training environments.</p>



<p>PyCharm helps you keep these workflows together in a single project while using isolated Python environments for each model family. Its interpreter management, built-in terminal, <em>Python Packages</em> tool window, and support for remote development make it easier to move between environments and run training on remote GPU hardware without having to manage each part of this workflow separately.</p>



<p>If you’d like to try these experiments yourself, maybe look into fine-tuning these models for your own specific object detection use case! PyCharm is available to download and try. You can use the accompanying project code to reproduce our COCO baselines, download the RF100 datasets, fine-tune the models, and evaluate them using the held-out test splits.</p>



<p>You can find the <a href="https://github.com/ArinaBelova/sota-object-detection-tutorial" target="_blank" rel="noopener">full code for this project on GitHub</a>. And if you’d like to learn more about object detection, including the architectures behind the models we used in this post, check out the <a href="https://blog.jetbrains.com/pycharm/2026/07/best-object-detection-models-for-machine-learning-in-2026/">previous post in this series</a>.</p>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The State of Django 2026: Boring is so back</title>
		<link>https://blog.jetbrains.com/pycharm/2026/08/the-state-of-django-2026-boring-is-so-back/</link>
		
		<dc:creator><![CDATA[Will Vincent]]></dc:creator>
		<pubDate>Fri, 28 Aug 2026 14:17:28 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/08/Django_Preview_1280x720.png</featuredImage>		<category><![CDATA[pycharm]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[state-of-django]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=pycharm&#038;p=734624</guid>

					<description><![CDATA[Welcome to the highlights from the fifth annual Django Developers Survey, a collaboration between the Django Software Foundation and PyCharm. This year’s report draws on responses from nearly 3,500 Django developers across more than 40 countries — from students in their first year to veterans with decades of experience. In software, &#8220;boring&#8221; is a compliment. [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Welcome to the highlights from the fifth annual <a href="https://lp.jetbrains.com/django-developer-survey-2026/" target="_blank" rel="noopener">Django Developers Survey</a>, a collaboration between the <a href="https://www.djangoproject.com/foundation/" target="_blank" rel="noopener">Django Software Foundation</a> and <a href="https://www.jetbrains.com/pycharm/web-development/django/" target="_blank" rel="noopener">PyCharm</a>. This year’s report draws on responses from nearly 3,500 Django developers across more than 40 countries — from students in their first year to veterans with decades of experience.</p>



<p>In software, &#8220;boring&#8221; is a compliment. It means a technology works so reliably you can stop thinking about it. By that standard, Django in 2026 is thriving: PostgreSQL has been the database of choice for 76–79% of respondents for five consecutive years, Django&#8217;s template engine has held steady at around 80%, and nearly half of developers upgrade with every stable release — 43% are already on Django 6.0, months after it shipped. The core is boring in the best possible way. Mature, but not static.</p>



<p>Everything around that core, though, is moving fast. AI is now an everyday tool for most developers, and agents are beginning to move beyond answering questions to editing files, running commands, and completing larger tasks. Newer tools are consolidating workflows that once required several separate utilities, typing is becoming standard practice, and the boundaries between editors, terminals, automation, and AI are getting blurrier.</p>



<p>That may be Django’s particular advantage in 2026: it is mature enough to be dependable, active enough to keep moving, and stable enough to give developers room to change almost everything else.</p>



<p><em>As an open-source framework, Django depends on its community and needs funding to remain healthy and secure. The PyCharm team runs an annual fundraiser to support Django.</em></p>



<p><em>Until September 10, get PyCharm at 30% off, and JetBrains will donate 100% of your purchase amount to the Django Software Foundation.</em></p>


    <div class="buttons">
        <div class="buttons__row">
                                                <a href="https://www.jetbrains.com/pycharm/promo/support-django/" class="btn" target="" rel="noopener">Get PyCharm at 30% off, and support Django</a>
                                                    </div>
    </div>







<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/Blog_infographics_2-3.png" alt="" class="wp-image-734782"/></figure>



<h2 class="wp-block-heading">1. AI is mainstream, but no workflow has won</h2>



<p>AI has become part of the normal Django development workflow. Only 10% of respondents said they regularly use no AI tools for coding, while 58% of AI users use them every day and another 27% several times a week.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/Blog_graph_1.png" alt="" class="wp-image-734651"/></figure>



<p>What remains unsettled is how developers use them. The interfaces are split almost evenly across the browser, the IDE, and the command line, and no tool dominates: Claude Code leads at 35%, with ChatGPT just behind at 33% and GitHub Copilot at 23%. And for all the attention on agents, a majority of AI users — 56% — still use it purely for chat and advice.</p>



<h2 class="wp-block-heading">2. Dominating AI workflow is still supervised</h2>



<p>Nearly half of AI users already work with AI through an IDE integration. But despite the growth of coding agents, the dominant workflow is still supervised: 59% have AI generate code and then apply the changes themselves, 44% let it edit files or run commands when instructed, and only 27% use it to autonomously complete multi-step tasks.</p>



<p>The emerging pattern is therefore less “replace the IDE with an agent” and more “bring the agent into the development environment.” Developers are adopting AI quickly, but the editor remains their home base for understanding the codebase, reviewing changes, and deciding what makes it into the project.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/Blog_graph_2.png" alt="" class="wp-image-734662"/></figure>



<p>Nowhere is the shift clearer than in how developers learn. Django&#8217;s official documentation remains the top resource at 67%, but AI tools are now second at 51% — ahead of YouTube, reading source code, and Stack Overflow.</p>



<p>AI is already routine for writing code, debugging, research, and learning. But developers are still experimenting with where it belongs: in the browser, inside the IDE, at the terminal, or increasingly, acting directly on the codebase.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>AI is changing the IDE faster than it is replacing it.</strong></p>
</blockquote>



<h2 class="wp-block-heading">3. Python tooling is consolidating fast</h2>



<p>Two tools that barely existed a few years ago are already near the top of the survey.</p>



<p>uv, released in February 2024, is already used by 43% of respondents for managing Python environments—second only to venv at 63% and ahead of Docker at 31%.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/Blog_graph_3.png" alt="" class="wp-image-734673"/></figure>



<p>Ruff tells a similar story. At 43%, it is now the most widely used code-quality and formatting tool in the survey, ahead of IDE inspections at 27%, Black at 25%, pre-commit at 20%, and Flake8 at 17%.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/Blog_graph_4.png" alt="" class="wp-image-734684"/></figure>



<p>The shift is not that Python’s older tools have disappeared. It is that newer tools increasingly cover jobs that once required several separate utilities. The result is a Python toolchain beginning to consolidate around fewer, faster, more capable tools.</p>



<h2 class="wp-block-heading">4. Type hints are winning. The type checker race is wide open.</h2>



<p>Type hints are becoming the norm in Django development: 57% already use them, and another 26% plan to. What is much less settled is how developers check those types.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/Blog_graph_5-1.png" alt="" class="wp-image-734695"/></figure>



<p>Among developers who use type hints, the most popular option isn&#8217;t a standalone type checker at all: 40% rely on the checker built into their IDE. Mypy follows at 32%, Ruff at 29%, and Pyright/Pylance at 22%. Newer entrants are already appearing too, with Astral’s ty reaching 12% and Meta’s Pyrefly at 4%.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/Blog_graph_6.png" alt="" class="wp-image-734706"/></figure>



<p>The practice, in other words, is converging faster than the tooling. Django developers increasingly agree that types are useful, but there is still no consensus on which tool should enforce them—or whether a separate tool is necessary at all.</p>



<p>That makes type checking an interesting space to watch in 2027: will one of the newer standalone tools break away from the pack, or will type checking increasingly become something developers simply expect their IDE to provide?</p>



<h2 class="wp-block-heading">5. As AI writes more code, verification matters more</h2>



<p>AI is moving beyond suggestions and into the codebase. That makes automated verification more important, not less.</p>



<p>The survey can&#8217;t tell us whether AI is driving greater adoption of tests or CI. What it does show is that most Django developers already have the infrastructure agents need: pytest is used by 45% of respondents and unittest by 43%, with pytest-django at 34%. </p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/Blog_graph_7.png" alt="" class="wp-image-734757"/></figure>



<p>That testing culture sits alongside widespread CI/CD adoption — GitHub Actions is now used by a majority of respondents at 51%, with GitLab CI/CD at another 26%. Together, these create a natural feedback loop for agentic development: an agent can make a change, run the test suite, respond to failures, and hand the developer a result that has already passed the project&#8217;s checks.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/Blog_graph_8.png" alt="" class="wp-image-734717"/></figure>



<p>Not everyone has that loop in place: 19% of respondents write no automated tests at all. As more code is delegated to agents, that fifth of developers is working without the safety net that makes delegation trustworthy.</p>



<p>The emerging agentic workflow may depend as much on verification as generation. The more code we delegate, the more valuable it becomes to have tests and pipelines that can quickly tell both developers and agents whether a change actually works.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>Agents can generate code. Tests and pipelines tell them whether it works.</strong></p>
</blockquote>



<h2 class="wp-block-heading">6. One framework, two ways to build</h2>



<p>Two distinct ways of building with Django are now firmly mainstream: letting Django render the interface, or using it as the backend for a separate frontend. 72% of respondents use server-rendered templates, while 53% use Django for API-only applications and 46% use it as the backend for a single-page application or dedicated JavaScript frontend.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/Blog_graph_9.png" alt="" class="wp-image-734730"/></figure>



<p>The balance is even clearer when developers are asked for their primary approach. Half primarily build server-rendered applications, while 44% primarily use Django for either APIs or dedicated JavaScript frontends.</p>



<p>The JavaScript numbers tell the sharper story. React has barely moved in five years — 37% in 2021, 38% today. What&#8217;s changed is everything around it: jQuery has fallen from 37% to 23%, Vue from 28% to 17%, while htmx has climbed from just 5% to 34%. htmx isn&#8217;t taking share from React — it&#8217;s modernizing the server-rendered side of the divide that jQuery used to own.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/Blog_graph_10.png" alt="" class="wp-image-734742"/></figure>



<p>That flexibility is one of Django’s strengths. The same framework can sit at the center of a hypermedia application or behind an API consumed by React, mobile apps, or other clients. </p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Django remains unusually comfortable on both sides of the frontend divide.</p>
</blockquote>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p></p>
</blockquote>



<h2 class="wp-block-heading">Conclusion</h2>



<p>Across the survey, the pattern is consistent: developers are changing their tools and workflows far faster than they are changing the framework underneath them. The parts of Django they value most remain familiar — models, the admin, authentication — and even deployment stays defiantly unfashionable, with 54% shipping monoliths and 44% self-hosting.</p>



<p>Even where Django itself is evolving, it does so deliberately: 33% of respondents use its async features and another 40% plan to — change offered as an opt-in, not a rewrite.</p>



<p>That stability is increasingly valuable. Developers can experiment with a new agent, replace several tools with Ruff or uv, add htmx to a template, or adopt a new type checker without having to rethink the framework underneath their application.</p>



<p>Django&#8217;s advantage in 2026 is not that it is the newest thing. It is that it gives developers a solid, dependable — yes, boring — place from which to try the newest things. Boring is so back.</p>



<h2 class="wp-block-heading">PyCharm for Django Fundraiser</h2>



<p>Get a new PyCharm Pro license or renew your existing one at 30% off, with 100% of your purchase amount going to the Django Software Foundation.</p>


    <div class="buttons">
        <div class="buttons__row">
                                                <a href="https://www.jetbrains.com/pycharm/promo/support-django/" class="btn" target="_blank" rel="noopener">Get PyCharm at 30% off, and support Django</a>
                                                    </div>
    </div>







<p>Explore the complete <a href="https://lp.jetbrains.com/django-developer-survey-2026/" target="_blank" rel="noopener">2026 Django Developers Survey Results</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Security Incident Affecting JetBrains Cadence</title>
		<link>https://blog.jetbrains.com/pycharm/2026/08/cadence-security-incident-august-2026/</link>
		
		<dc:creator><![CDATA[Daniel Gallo]]></dc:creator>
		<pubDate>Fri, 28 Aug 2026 09:50:14 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/08/JB-social-BlogFeatured-1280x720-1-9.png</featuredImage>		<category><![CDATA[news]]></category>
		<category><![CDATA[security]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=pycharm&#038;p=734588</guid>

					<description><![CDATA[We are investigating a security incident affecting JetBrains Cadence. Cadence is a JetBrains-hosted service that integrates with PyCharm through an optional plugin, and lets you run your projects on cloud compute resources. Our investigation has confirmed unauthorized access to the service and the exposure of customer data associated with its use. We have contacted affected [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>We are investigating a security incident affecting JetBrains Cadence. Cadence is a JetBrains-hosted service that integrates with PyCharm through an optional plugin, and lets you run your projects on cloud compute resources. Our investigation has confirmed unauthorized access to the service and the exposure of customer data associated with its use.</p>



<p>We have contacted affected users directly and have taken steps to contain the incident.</p>



<p><strong>This post provides the latest information about the incident, its potential impact, and the actions we recommend Cadence users take. We will update it as our investigation progresses and additional information becomes available.</strong></p>



<p><strong>Last updated: </strong>September 3, 2026, 19:00 CEST</p>



<h2 class="wp-block-heading">September 3, 2026, 19:00 CEST</h2>



<p>Our investigation has identified additional potential exposure involving storage used by the current Cadence environment.</p>



<p>We confirmed that the threat actor obtained access that could have allowed them to reach storage containing data associated with current Cadence users, including email addresses, project source code, and credentials. This affects the same group of users we previously contacted directly. These findings did not identify any additional affected users. As a precaution, we are treating the data stored there as potentially exposed.&nbsp;</p>



<p>Our investigation has now concluded. The recommended actions for affected users remain unchanged.</p>



<h2 class="wp-block-heading">September 1, 2026, 12:05 CEST</h2>



<p>Our investigation is nearing completion, and most mitigation and response actions are now finalized. We have not identified any additional compromised resources or data since our last update, and we are wrapping up a small number of remaining verification activities. The recommended actions for affected users remain unchanged.</p>



<h2 class="wp-block-heading">August 31, 2026, 12:56 CEST</h2>



<p>Our investigation remains ongoing. At this time, we have not identified any additional compromised resources or data.</p>



<p>We have confirmed that the threat actor accessed data contained in the Cadence server backup from 2024. At this time, there is no evidence to suggest that the threat actor extracted data, including secrets, from the current Cadence environment.</p>



<p>The recommended actions described below remain unchanged.</p>



<h2 class="wp-block-heading">August 28, 2026, 11:50 CEST</h2>



<p><a href="https://blog.jetbrains.com/pycharm/2025/06/training-your-ml-models-with-cadence/">Cadence</a> is a JetBrains-hosted service integrated with PyCharm through an optional plugin, that lets you run your projects on cloud compute resources. Cadence uses JetBrains TeamCity to orchestrate this work. We recently disclosed <a href="https://blog.jetbrains.com/teamcity/2026/07/cve-2026-63077/">CVE-2026-63077</a>, a critical vulnerability in TeamCity that can allow an unauthenticated attacker to execute arbitrary commands on a vulnerable server.</p>



<p>We have since confirmed the Cadence environment was vulnerable to CVE-2026-63077 and was exploited through this vulnerability.</p>



<p>Cadence users should immediately revoke or rotate all credentials and secrets that may have been used to run their Cadence executions. They should also treat all executions, including their inputs and outputs in your Cadence project, as potentially untrusted.</p>



<h3 class="wp-block-heading"><strong>Actions required immediately</strong></h3>



<p>We strongly recommend that Cadence users:</p>



<ul class="wp-block-list">
<li>Revoke and rotate all credentials and secrets that may have been used to run Cadence executions.</li>



<li>Review connected systems for suspicious activity, particularly AWS accounts, S3 buckets, deployment environments, package/container registries, and other systems accessible using credentials mentioned above.</li>



<li>Review source code repositories for unauthorized changes made during the affected period.</li>



<li>Review any source code or project files synchronized to Cadence from PyCharm and rotate any credentials, tokens, or other sensitive information contained within them.</li>



<li>Treat all executions, including their inputs and outputs in your Cadence project, as potentially untrusted.</li>
</ul>



<p>Cadence users can contact us to request an inventory of the credentials and secrets associated with their Cadence usage. This may help users identify which credentials need to be revoked or rotated, but the inventory should not be considered exhaustive.</p>



<p>We have collated a list of Indicators of Compromise (IoCs) below. These indicators are not exhaustive, and the absence of these indicators does not confirm that an account or system was unaffected:</p>



<ul class="wp-block-list">
<li>Activity occurring from August 8, 2026, onwards, particularly authentication or activity using credentials previously stored in or accessible through Cadence.</li>



<li>IP addresses associated with observed exploitation activity:
<ul class="wp-block-list">
<li>150.109.230.104</li>



<li>43.153.227.206</li>



<li>62.210.127.48</li>



<li>210.247.242.190</li>



<li>15.235.225.205</li>



<li>152.233.30.18</li>
</ul>
</li>



<li>Authentication or other activity from unexpected IP addresses or locations.</li>



<li>Unexpected repository clones or downloads, and unexpected commits to repositories.</li>



<li>Changes to repository secrets, webhooks, collaborators, or permissions.</li>



<li>New or modified personal access tokens, API tokens, or SSH keys in external services.</li>



<li>New service accounts created in external services.</li>



<li>Unexpected changes to cloud IAM roles, policies, or permissions.</li>



<li>Unexpected access to cloud storage, including S3 buckets and objects, in services such as AWS and Google Cloud.</li>



<li>Unexpected publication or modification of packages or releases.</li>
</ul>



<h3 class="wp-block-heading"><strong>Affected server</strong></h3>



<p>We have confirmed that the following Cadence server was successfully exploited: <code>api.cadence.jetbrains.com</code>.</p>



<h3 class="wp-block-heading"><strong>Affected period</strong></h3>



<p>August 8, 2026, to August 24, 2026.</p>



<h3 class="wp-block-heading"><strong>What happened</strong></h3>



<p>The Cadence server used TeamCity to orchestrate workloads and was vulnerable to CVE-2026-63077. Threat actors exploited the vulnerability and gained unauthorized access to the affected Cadence environments, with activity identified from August 8, 2026. We discovered the exploitation on August 23, 2026, and took the affected server offline on August 24, 2026, while we continued our investigation.</p>



<h3 class="wp-block-heading"><strong>What we know</strong></h3>



<p>Our investigation is ongoing, but we have confirmed that the threat actors:</p>



<ul class="wp-block-list">
<li>Accessed personal data and extracted it from the affected environment. Confirmed affected personal data includes usernames, real names, email addresses, last-login timestamps, and last accessed IP addresses.</li>



<li>Compromised a full backup of the Cadence server dating from 2024. This means credentials, configuration, artifacts, logs, or other data present in that backup must also be treated as potentially exposed.</li>



<li>Compromised multiple AWS IAM users and associated credentials/secrets used with Cadence, including IAM users belonging to JetBrains employees who used the service. These credentials were present in the compromised 2024 backup.</li>



<li>Accessed files stored in S3 buckets within JetBrains AWS accounts used by Cadence. We are still determining the full scope of the data accessed. We do not currently know whether the threat actors accessed storage buckets in customer accounts. However, some users may have configured Cadence to access their own storage buckets, and the credentials used for those connections may have also been exposed.</li>



<li>May have accessed source code synchronized from PyCharm projects to the affected server. If you used PyCharm to upload or synchronize project files for execution in Cadence, you should treat that code, and any credentials or configuration contained within it, as potentially compromised.</li>
</ul>



<p>The likely consequences of the personal data exposure include an increased risk of targeted phishing, social engineering, impersonation, and other unsolicited or malicious communications using the affected names and email addresses.</p>



<p>As the threat actors gained access to the Cadence server, any credentials or secrets stored in Cadence, contained in the compromised backup, or made available to executions on the affected server should be considered compromised and must be revoked or rotated.</p>



<p>This includes but is not limited to:</p>



<ul class="wp-block-list">
<li>Cloud credentials, including AWS, Azure, and Google Cloud.</li>



<li>Source control credentials and tokens, including GitHub, GitLab, and Bitbucket.</li>



<li>Package repository credentials, including npm, Maven, NuGet, PyPI, and similar services.</li>



<li>Container registry credentials, including Docker Hub, ECR, GCR, ACR, and other registries.</li>



<li>Slack tokens, webhooks, API tokens, SSH/deployment keys, service account credentials, signing keys/certificates, and credentials for any other external systems used by your Cadence executions.</li>
</ul>



<h3 class="wp-block-heading"><strong>Actions JetBrains has taken</strong></h3>



<p>We took the Cadence server offline on August 24, 2026, while we continue to investigate the incident. At present, we have confirmed that the incident is limited to data associated with the Cadence host mentioned above.</p>



<p>The server should have been patched as part of our response to the vulnerability, but it was not. We sincerely apologize for this failure and the impact it may have on you.</p>



<p>We have invalidated all access tokens used by the JetBrains Cadence plugin in PyCharm to connect to Cadence, and took the server offline on August 24, 2026.</p>



<p>We are also notifying the relevant authorities and taking the necessary steps to protect the data of Cadence users.</p>



<h3 class="wp-block-heading"><strong>Further updates</strong></h3>



<p>We will publish further findings and guidance here as our investigation progresses. We recommend checking this page frequently for the latest information. We will also contact affected users directly if we identify any important new information that may require action on their part.</p>



<p>For more information about the underlying vulnerability, please see our original <a href="https://blog.jetbrains.com/teamcity/2026/07/cve-2026-63077/">security advisory</a> to TeamCity customers and users.</p>



<p>If you previously used Cadence and need assistance identifying which credentials may have been exposed or have any questions regarding this incident, contact the JetBrains Security team at <a href="mailto:security@jetbrains.com?subject=Security incident affecting JetBrains Cadence">security@jetbrains.com</a>.</p>



<p>We recognize the seriousness of this incident and apologize again for the impact.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>OpenTelemetry Comes to IntelliJ IDEA, GoLand, PyCharm, and WebStorm</title>
		<link>https://blog.jetbrains.com/platform/2026/08/opentelemetry-plugin-for-jetbrains-ides/</link>
		
		<dc:creator><![CDATA[Egor Klimov]]></dc:creator>
		<pubDate>Wed, 26 Aug 2026 07:40:10 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/08/JB-social-BlogFeatured-1280x720-1-6.png</featuredImage>		<product ><![CDATA[go]]></product>
		<product ><![CDATA[pycharm]]></product>
		<product ><![CDATA[webstorm]]></product>
		<category><![CDATA[goland]]></category>
		<category><![CDATA[idea]]></category>
		<category><![CDATA[intellij-platform]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[pycharm]]></category>
		<category><![CDATA[research]]></category>
		<category><![CDATA[rider]]></category>
		<category><![CDATA[webstorm]]></category>
		<category><![CDATA[intellij-idea]]></category>
		<category><![CDATA[opentelemetry]]></category>
		<category><![CDATA[performance-optimization]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=platform&#038;p=733710</guid>

					<description><![CDATA[OpenTelemetry Comes to IntelliJ IDEA, GoLand, PyCharm, and WebStorm. The OpenTelemetry plugin has broken out of the confines of JetBrains Rider. No sandbox exploit was involved – this escape was planned by our developers. With the 2026.2 release, the OpenTelemetry plugin is now available in IntelliJ IDEA, GoLand, PyCharm and WebStorm. Rider users needn’t worry [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>OpenTelemetry Comes to IntelliJ IDEA, GoLand, PyCharm, and WebStorm.</p>



<p>The <a href="https://plugins.jetbrains.com/plugin/27488-opentelemetry/" target="_blank" rel="noopener">OpenTelemetry plugin</a> has broken out of the confines of JetBrains Rider. No sandbox exploit was involved – this escape was planned by our developers. With the 2026.2 release, the OpenTelemetry plugin is now available in IntelliJ IDEA, GoLand, PyCharm and WebStorm. Rider users needn’t worry – it still works there too.</p>



<p>The plugin brings logs, metrics, traces, and the service map from local applications into the IDE. You can inspect them without setting up a separate local observability backend.</p>


    <div class="buttons">
        <div class="buttons__row">
                                                <a href="https://plugins.jetbrains.com/plugin/27488-opentelemetry/" class="btn" target="_blank" rel="noopener">Get the OTel plugin from the Marketplace</a>
                                                    </div>
    </div>







<h2 class="wp-block-heading">What is the OpenTelemetry plugin?</h2>



<p>While developing with your IDE, you can use the plugin to:</p>



<ul class="wp-block-list">
<li>Find what happened immediately before an error.</li>



<li>See which services and dependencies a request reached.</li>



<li>Pinpoint where a request spent its time.</li>



<li>Check whether the application emitted the expected logs, metrics, and traces.</li>



<li>Ask your coding agent to do all of the above via <a href="https://www.jetbrains.com/help/idea/mcp-server.html" target="_blank" rel="noopener">MCP</a>.</li>
</ul>



<p></p>



<p>The plugin’s functionality complements what the IDE offers out of the box. Use a debugger to step through code, a profiler to analyze performance, and a production monitoring platform to watch deployed systems. Use the OpenTelemetry plugin to inspect runtime behavior while you build or test the application.</p>



<h2 class="wp-block-heading">Imagine this</h2>



<p>Say you are testing a feature that calls several services and a database before publishing a message to a queue. The request fails, and the console shows the exception, but not the path that led to it.</p>



<p>In the <em>OpenTelemetry</em> tool window, you can search the logs for the error. Open the relevant trace to see how the request moved through the system and where it failed. The <em>Service Map</em> shows the services and infrastructure involved.</p>



<h2 class="wp-block-heading">Explore runtime data in the IDE</h2>



<h3 class="wp-block-heading">Search and inspect logs</h3>



<p>Console output is manageable until several services start writing at once. The <em>Logs</em> view puts OpenTelemetry log records in a searchable table. You can filter by severity or content, then open a record to inspect its attributes.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/image3-3.png" alt="" class="wp-image-733792"/><figcaption class="wp-element-caption"><em>Detailed log view showing timestamps, levels, and messages for different log types</em></figcaption></figure>



<h3 class="wp-block-heading">Check metrics</h3>



<p>Select a metric from the metric tree to plot its values while you use the application. This view is not a replacement for your production dashboards, but it lets you inspect what the application will export before you send the data to a production observability platform. If a new library adds noisy or unnecessary metrics, you can catch them locally and adjust the instrumentation before your DevOps and SRE colleagues have to handle them.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/image2.png" alt="" class="wp-image-733803"/><figcaption class="wp-element-caption"><em>The metrics viewer displays CPU utilization data with real-time charts.</em></figcaption></figure>



<h3 class="wp-block-heading">Follow a request through its trace</h3>



<p>Open a trace to see its spans across services. Each span includes timing and attributes, so you can follow the request from start to finish and zero in on the operation that failed or slowed things down. Development is also a good time to look at the trace itself. Does it contain the spans and details you&#8217;d need during a real incident? It&#8217;s much easier to fix those gaps now than to discover them in production.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/image4-2.png" alt="" class="wp-image-733781"/><figcaption class="wp-element-caption"><em><em>The trace table view with filtering capabilities and detailed information for the selected trace.</em></em></figcaption></figure>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/image1-1.png" alt="" class="wp-image-733814"/><figcaption class="wp-element-caption"><em>The trace viewer showing details of the POST request involving multiple internal DB and HTTP calls.</em></figcaption></figure>



<p></p>



<h3 class="wp-block-heading">See observed relationships in the <em>Service Map</em></h3>



<p>Architecture diagrams go stale. The <em>Service Map</em> builds its relationships from collected traces, so it reflects the traffic the plugin has seen between services, endpoints, databases, and message queues.</p>



<p>Expected one HTTP call or database query, but the diagram shows several? Finding that during development gives you time to fix it before release.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/image5-2.png" alt="" class="wp-image-733825"/><figcaption class="wp-element-caption"><em>Automatically generated service map showing the relationship between API endpoints, internal services, and PostgreSQL based on actual runtime traces.</em></figcaption></figure>



<h2 class="wp-block-heading">Connect an instrumented application</h2>



<p>The plugin does not add OpenTelemetry libraries or agents to your application. It configures where an already instrumented application sends its data.</p>



<p>Start an instrumented Java, Python, Go, or .NET application from a supported IDE run configuration, and the plugin passes OpenTelemetry Protocol (OTLP) environment variables that point to its built-in receiver. It passes the same variables to new integrated terminal sessions.</p>



<p>You can also point the application&#8217;s OTLP exporter at the endpoint shown by the plugin. If you already use a local OpenTelemetry Collector, add the plugin as an OTLP destination and keep the rest of your pipeline.</p>



<h2 class="wp-block-heading">Runtime context for coding agents</h2>



<p>The plugin has experimental MCP support through the <a href="https://plugins.jetbrains.com/plugin/26071-mcp-server" target="_blank" rel="noopener">JetBrains MCP server</a>. A compatible coding agent can query the telemetry collected in the IDE with these tools:</p>



<ul class="wp-block-list">
<li><code>get_log_records</code></li>



<li><code>get_spans</code></li>



<li><code>get_services</code></li>



<li><code>get_service_map</code></li>
</ul>



<p>These tools give the agent evidence from a particular run, so that it can inspect the logs and spans or query the observed service relationships.</p>



<h2 class="wp-block-heading">Getting started</h2>



<ol class="wp-block-list">
<li>Install the <a href="https://plugins.jetbrains.com/plugin/27488-opentelemetry/" target="_blank" rel="noopener">OpenTelemetry plugin from JetBrains Marketplace</a> for your favorite IDE.</li>



<li>Instrument your application with OpenTelemetry libraries or agents.</li>



<li>Start it from a supported IDE run configuration or a new integrated terminal session. The plugin will pass the OTLP environment variables. Alternatively, point the application&#8217;s exporter or your local collector at the endpoint shown by the plugin.</li>



<li>Open the <em>OpenTelemetry</em> tool window and exercise the part of the application you want to inspect.</li>
</ol>



<p>The plugin shows the signals it receives. If your application exports only traces, the <em>Logs</em> and <em>Metrics</em> views stay empty.</p>



<p>Full setup instructions are available in the <a href="https://www.jetbrains.com/help/rider/OpenTelemetry.html" target="_blank" rel="noopener">OpenTelemetry plugin documentation</a>.</p>



<h2 class="wp-block-heading">Install it and tell us what you find</h2>


    <div class="buttons">
        <div class="buttons__row">
                                                <a href="https://plugins.jetbrains.com/plugin/27488-opentelemetry/" class="btn" target="_blank" rel="noopener">Get the OTel plugin from the Marketplace</a>
                                                    </div>
    </div>







<p>Try it on a real project, then tell us in the comments or through the <a href="https://youtrack.jetbrains.com/projects/RIDER/issues/RIDER-102188/OpenTelemetry-plugin-for-Rider" target="_blank" rel="noopener">issue tracker</a> what worked and what still sent you to another tool.</p>



<h2 class="wp-block-heading">Some final notes</h2>



<p>This plugin is the product of a collaborative effort between the Rider Execution team and the Dynamic Program Analysis Research team at JetBrains Research. This launch is the first step in exploring how telemetry analysis can help us build development tools that better adapt to real-world developer workflows.</p>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>PyCharm for AI-assisted Django Workflows</title>
		<link>https://blog.jetbrains.com/pycharm/2026/08/pycharm-for-ai-assisted-django-workflows/</link>
		
		<dc:creator><![CDATA[Will Vincent]]></dc:creator>
		<pubDate>Thu, 20 Aug 2026 13:06:50 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/08/PC-social-BlogFeatured-1280x720-1-1.png</featuredImage>		<category><![CDATA[agentic-ai]]></category>
		<category><![CDATA[ai]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[web-development]]></category>
		<category><![CDATA[django]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=pycharm&#038;p=731652</guid>

					<description><![CDATA[The 2026 Django Developers Survey found that AI is part of the weekly or daily workflow for 90% of respondents. AI can write code quickly, but Django developers still need to understand the application, evaluate what the agent produces, and be accountable for what ships. That makes your IDE more important, not less. PyCharm gives [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>The <em><a href="https://lp.jetbrains.com/django-developer-survey-2026/" target="_blank" rel="noopener">2026 Django Developers Survey</a></em> found that AI is part of the weekly or daily workflow for 90% of respondents. AI can write code quickly, but Django developers still need to understand the application, evaluate what the agent produces, and be accountable for what ships.</p>



<p>That makes your IDE more important, not less. PyCharm gives you the freedom to choose the agents and models you want, as well as extensive Python and Django support for understanding and reviewing the code they produce.</p>



<h3 class="wp-block-heading">1. Bring your own agent</h3>



<p>Leading agents such as Codex, Claude Agent, Junie, and Gemini run natively in PyCharm, while the <a href="https://agentclientprotocol.com/get-started/registry" target="_blank" rel="noopener">ACP registry</a> gives you access to dozens more, installable in a click from the same dropdown menu. You can use a JetBrains AI subscription or bring your own tools – the choice is yours.</p>



<p>Want to use your own model? <a href="https://www.jetbrains.com/help/ai-assistant/bring-your-own-key-byok.html" target="_blank" rel="noopener">Bring Your Own Key</a> technology lets you connect existing provider credentials, while Ollama and LM Studio let you work with local models.</p>



<p>You choose the AI tools that fit your workflow. PyCharm doesn&#8217;t lock you into one provider.</p>



<figure class="wp-block-video"><video controls src="https://blog.jetbrains.com/wp-content/uploads/2026/08/1_AIChat_Dropdown.webm"></video></figure>



<h3 class="wp-block-heading">2. Teach your agent your conventions</h3>



<p>Skills give your agent reusable instructions and context. In PyCharm 2026.2, native skill support for Claude Agent and Codex lets you add a skill directly from the AI chat, either for a single project or across your entire codebase.</p>



<p>The curated <a href="https://blog.jetbrains.com/ai/2026/04/skill-manager-and-skill-repository/">Skill Repository</a> also gives you a way to add official skills for technologies, including React, Postgres, and Playwright.</p>



<p>Skills let you encode useful context once and reuse it, so you spend less time repeating instructions to your agents.</p>



<figure class="wp-block-video"><video controls src="https://blog.jetbrains.com/wp-content/uploads/2026/08/2_Agent_Skills.webm"></video></figure>



<h3 class="wp-block-heading">3. Django 6+ support</h3>



<p>PyCharm keeps up with Django&#8217;s release cycle, including<a href="https://www.jetbrains.com/help/pycharm/django-6-template-partials.html" target="_blank" rel="noopener"> Django 6.0 template partials</a>. The IDE understands the new partial template tags and completes them as you type.</p>



<p>This matters especially when frameworks evolve. An agent&#8217;s training data may not reflect the exact Django version you&#8217;re running. PyCharm&#8217;s Django support is tied to the version in your project.</p>



<figure class="wp-block-video"><video controls src="https://blog.jetbrains.com/wp-content/uploads/2026/08/3_Django60_Template_Partials.webm"></video></figure>



<h3 class="wp-block-heading">4. Review with confidence</h3>



<p>AI generates code quickly, which makes reviewing and undoing changes more important than ever.</p>



<p>PyCharm gives you visual diffs, merge tools, integrated conflict resolution, and Git history in the IDE, so you can inspect changes before committing or merging.</p>



<p><a href="https://www.jetbrains.com/help/pycharm/local-history.html" target="_blank" rel="noopener">Local History</a> works independently of version control, recording changes as you work. You can compare a file with an earlier state and restore a version from before the agent touched it – even if you never committed the change.</p>



<figure class="wp-block-video"><video controls src="https://blog.jetbrains.com/wp-content/uploads/2026/08/4_Review_Confidence.webm"></video></figure>



<h3 class="wp-block-heading">5. See your Django architecture</h3>



<p>Django applications can get big<strong>. </strong><a href="https://www.jetbrains.com/help/pycharm/django-logical-structure.html" target="_blank" rel="noopener">Django Logical Structure</a> presents your project from Django&#8217;s point of view rather than as a flat collection of Python and HTML files. You can follow a model to its serializer, its views, and the endpoints they serve.</p>



<p>Whether the code you&#8217;re reading was written by you six months ago, another developer, or an agent, PyCharm helps you understand how the pieces fit together.</p>



<figure class="wp-block-video"><video controls src="https://blog.jetbrains.com/wp-content/uploads/2026/08/5_Django_Structure.webm"></video></figure>



<h3 class="wp-block-heading">6. Verify your API and your data</h3>



<p>The<a href="https://www.jetbrains.com/help/pycharm/endpoints-tool-window.html" target="_blank" rel="noopener"><em> </em><em>Endpoints </em>tool window</a> gives you a structured view of your Django endpoints, including documentation, examples, generated HTTP requests, and OpenAPI information. You can send those requests directly with the built-in HTTP Client.</p>



<p>The same idea applies to your database. The<a href="https://www.jetbrains.com/help/pycharm/data-editor-and-viewer.html" target="_blank" rel="noopener"> data editor and viewer</a> let you browse and query application data without leaving the IDE. After an agent generates a migration, you can inspect the resulting data and verify that the change did what you expected.</p>



<figure class="wp-block-video"><video controls src="https://blog.jetbrains.com/wp-content/uploads/2026/08/6_Export_API_DB.webm"></video></figure>



<h3 class="wp-block-heading">The IDE outlasts the agent</h3>



<p>AI tooling is changing fast, but your developer workflow can stay consistent. PyCharm combines deep Python and Django support with access to the agents and models you choose.</p>



<p>Get 30% off PyCharm, and JetBrains will donate 100% of what you pay to the Django Software Foundation.</p>


    <div class="buttons">
        <div class="buttons__row">
                                                <a href="https://www.jetbrains.com/pycharm/promo/support-django/" class="btn" target="" rel="noopener">Get 30% off PyCharm</a>
                                                    </div>
    </div>




]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>What’s Fixed and Improved in PyCharm 2026.2</title>
		<link>https://blog.jetbrains.com/pycharm/2026/08/what-s-fixed-and-improved-in-pycharm-2026-2/</link>
		
		<dc:creator><![CDATA[Will Vincent]]></dc:creator>
		<pubDate>Wed, 19 Aug 2026 13:54:13 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/08/Whats-fixed-2026-2-BlogFeatured-1280x720-1.png</featuredImage>		<category><![CDATA[releases]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[web-development]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=pycharm&#038;p=731629</guid>

					<description><![CDATA[Across the PyCharm 2026.2 release line, we shipped 263 fixes and improvements. Many improve Python code insight directly, with more precise type inference, fewer false positives, smarter completion and imports, and more reliable refactoring. Here are some of the smaller changes you’re likely to notice in everyday Python development. SQLAlchemy 2.0 support SQLAlchemy has been [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Across the PyCharm 2026.2 release line, we shipped<a href="https://youtrack.jetbrains.com/issues?q=%23py%20type:%20bug%20%23resolved%20Planned%20for:%202026.2,%20%7B2026.2%20*%7D,%202026.2.1%20visible%20to:%20%7BAll%20Users%7D" target="_blank" rel="noopener"> 263 fixes and improvements</a>. Many improve Python code insight directly, with more precise type inference, fewer false positives, smarter completion and imports, and more reliable refactoring. Here are some of the smaller changes you’re likely to notice in everyday Python development.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">SQLAlchemy 2.0 support</h2>



<p>SQLAlchemy has been a long-standing source of false positives – enough that several duplicate tickets have accumulated over the years. This release resolves a batch of them for the 2.0 style.</p>



<p>String forward-references inside <code>Mapped[...]</code> resolve correctly:</p>



<pre class="EnlighterJSRAW">posts: Mapped&#091;list&#091;&quot;Post&quot;]] = relationship(back_populates=&quot;author&quot;)

# &quot;Post&quot; now resolves to the model class</pre>



<p>PyCharm also correctly infers the mapped type returned by <code>Session.get()</code>, instead of treating the result as the model class itself:</p>



<pre class="EnlighterJSRAW">report = session.get(Report, report_id)

reveal_type(report)&nbsp; # was: type&#091;Report] | None &nbsp; now: Report | None</pre>



<p>Modern <code>hybrid_property</code> setters written as <code>@name.inplace.setter</code> are recognized, so assigning to the property no longer produces a warning. Model class attributes defined via mixins are picked up again, too, clearing the old <em>unexpected argument</em> reports on model constructors.</p>



<p>(<a href="https://youtrack.jetbrains.com/issue/PY-78816" target="_blank" rel="noopener">PY-78816</a>,<a href="https://youtrack.jetbrains.com/issue/PY-65142" target="_blank" rel="noopener"> PY-65142</a>,<a href="https://youtrack.jetbrains.com/issue/PY-59732" target="_blank" rel="noopener"> PY-59732</a>,<a href="https://youtrack.jetbrains.com/issue/PY-51906" target="_blank" rel="noopener"> PY-51906</a>,<a href="https://youtrack.jetbrains.com/issue/PY-28762" target="_blank" rel="noopener"> PY-28762</a>)</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Code insight and type inference</h2>



<h3 class="wp-block-heading">Control-flow narrowing and &#8220;unreachable code&#8221;</h3>



<p>Several false <em>This code is unreachable</em> reports and instances of lost narrowing across loops have been fixed. The common issue: flow analysis either gave up or over-eagerly narrowed to <code>Never </code>in branches it should have kept alive.</p>



<p><code>isinstance</code> on a numeric union no longer kills the <code>else</code> branch:</p>



<pre class="EnlighterJSRAW">def foo(y: int | float) -&gt; None:

&nbsp;&nbsp;&nbsp;&nbsp;if isinstance(y, float):

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pass

&nbsp;&nbsp;&nbsp;&nbsp;else:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(y)&nbsp; # was flagged unreachable, y inferred as Never</pre>



<p>Narrowing also survives a <code>while</code> loop, so re-narrowing an optional attribute inside the loop body no longer reports a bogus <em>has no attribute</em> error.</p>



<p>(<a href="https://youtrack.jetbrains.com/issue/PY-83206" target="_blank" rel="noopener">PY-83206</a>,<a href="https://youtrack.jetbrains.com/issue/PY-83354" target="_blank" rel="noopener"> PY-83354</a>,<a href="https://youtrack.jetbrains.com/issue/PY-88265" target="_blank" rel="noopener"> PY-88265</a>)</p>



<h3 class="wp-block-heading">Strings inside type annotations</h3>



<p>A string used as metadata inside <code>Annotated[...]</code> – a Pydantic discriminator field name, for instance – is no longer parsed as a forward reference and flagged as unresolved.</p>



<p>(<a href="https://youtrack.jetbrains.com/issue/PY-48749" target="_blank" rel="noopener">PY-48749</a>,<a href="https://youtrack.jetbrains.com/issue/PY-82245" target="_blank" rel="noopener"> PY-82245</a>)</p>



<h3 class="wp-block-heading">Iterable unpacking and star expressions</h3>



<p>PyCharm&#8217;s analysis of tuple and star unpacking could lose type information and fall back to <code>Any</code>. Unpacking a starred value into a tuple lost its element types, <code>*</code>-expansion collapsed to <code>Any</code>, and several genuine errors went unreported. Starred expressions preserve their element types:</p>



<pre class="EnlighterJSRAW">def a() -&gt; tuple&#091;int, int]:

&nbsp;&nbsp;&nbsp;&nbsp;return 2, 3

def b() -&gt; tuple&#091;int, int, int]:

&nbsp;&nbsp;&nbsp;&nbsp;return (1, *a())&nbsp; # no more bogus &quot;Expected tuple&#091;int, int, int]&quot;</pre>



<p>(<a href="https://youtrack.jetbrains.com/issue/PY-12592" target="_blank" rel="noopener">PY-12592</a>,<a href="https://youtrack.jetbrains.com/issue/PY-27205" target="_blank" rel="noopener"> PY-27205</a>,<a href="https://youtrack.jetbrains.com/issue/PY-43585" target="_blank" rel="noopener"> PY-43585</a>,<a href="https://youtrack.jetbrains.com/issue/PY-90219" target="_blank" rel="noopener"> PY-90219</a>)</p>



<h3 class="wp-block-heading">Augmented assignment</h3>



<p>A cluster of false positives came from augmented assignments being misanalyzed. A simple <code>/=</code> on an <code>int</code> produced the wrong type:</p>



<pre class="EnlighterJSRAW">foo = 5

foo /= 2

reveal_type(foo)&nbsp; # was: int &nbsp; now: float | int</pre>



<p>(<a href="https://youtrack.jetbrains.com/issue/PY-80622" target="_blank" rel="noopener">PY-80622</a>)</p>



<h3 class="wp-block-heading"><code>Self</code> and constructor return types</h3>



<p><code>Self</code> binds correctly through <code>classmethod</code> parameters typed as <code>type[Self]</code>:</p>



<pre class="EnlighterJSRAW">class A:

&nbsp;&nbsp;&nbsp;&nbsp;@classmethod

&nbsp;&nbsp;&nbsp;&nbsp;def bar(cls, y: type&#091;Self]) -&gt; Self: ...

x = A.bar(A)&nbsp; &nbsp; &nbsp; # was a spurious &quot;Expected type&#091;A], got type&#091;A]&quot;

reveal_type(x)&nbsp; &nbsp; # was: Any &nbsp; now: A</pre>



<p>Construction also respects <code>__new__</code>, <code>__init__</code>, and metaclass <code>__call__</code>. When <code>__new__</code> returns something other than an instance, that&#8217;s the constructed type – even when an <code>__init__</code> is present. The same fix covers explicitly parameterized calls like <code>MyClass[int]()</code> and <code>__new__</code> assigned as a class attribute.</p>



<p>(<a href="https://youtrack.jetbrains.com/issue/PY-89296" target="_blank" rel="noopener">PY-89296</a>,<a href="https://youtrack.jetbrains.com/issue/PY-77611" target="_blank" rel="noopener"> PY-77611</a>,<a href="https://youtrack.jetbrains.com/issue/PY-88644" target="_blank" rel="noopener"> PY-88644</a>,<a href="https://youtrack.jetbrains.com/issue/PY-89571" target="_blank" rel="noopener"> PY-89571</a>)</p>



<h3 class="wp-block-heading">Enum members: Literal types for <code>.value</code> and <code>.name</code></h3>



<p>Reading an enum member&#8217;s <code>.value</code> or <code>.name</code> yields a precise <code>Literal</code> instead of a widened <code>str</code> or <code>int</code>, so assignments to <code>Literal[...]</code> target type-check. This matches <code>mypy</code>’s inference:</p>



<pre class="EnlighterJSRAW">from enum import Enum

from typing import Literal

class E(Enum):

&nbsp;&nbsp;&nbsp;&nbsp;a = &quot;a&quot;

b: Literal&#091;&quot;a&quot;] = E.a.value &nbsp; # was: Expected &#039;Literal&#091;&quot;a&quot;]&#039;, got &#039;str&#039;

n: Literal&#091;&quot;a&quot;] = E.a.name&nbsp; &nbsp; # .name is a Literal too</pre>



<p>(<a href="https://youtrack.jetbrains.com/issue/PY-61028" target="_blank" rel="noopener">PY-61028</a>,<a href="https://youtrack.jetbrains.com/issue/PY-79198" target="_blank" rel="noopener"> PY-79198</a>)</p>



<h3 class="wp-block-heading">Parameter types inferred from decorators</h3>



<p>When a decorator constrains the callable it accepts, the decorated function&#8217;s parameters are inferred from that constraint instead of falling back to <code>Any</code>:</p>



<pre class="EnlighterJSRAW">from typing import Callable

def d(fn: Callable&#091;&#091;int], str]): ...

@d

def f(a):

&nbsp;&nbsp;&nbsp;&nbsp;reveal_type(a) &nbsp; # was: Any &nbsp; now: int</pre>



<p>(<a href="https://youtrack.jetbrains.com/issue/PY-79204" target="_blank" rel="noopener">PY-79204</a>)</p>



<h3 class="wp-block-heading">Also fixed</h3>



<ul class="wp-block-list">
<li>Keyword arguments in a class header are validated against the base class&#8217;s <code>__init_subclass__</code> signature, and offered in completion (<a href="https://youtrack.jetbrains.com/issue/PY-79173" target="_blank" rel="noopener">PY-79173</a>).</li>



<li>An ellipsis in a <code>Callable</code> used as a PEP 695 type-parameter bound no longer reports a bogus <em>Invalid type expression</em> (<a href="https://youtrack.jetbrains.com/issue/PY-83570" target="_blank" rel="noopener">PY-83570</a>).</li>



<li>Type-checker findings are split into granular suppression codes rather than a single <code>PyTypeChecker</code> id, and <code># noinspection</code> directives accept a simplified name form. <code>PyTypeChecker</code> still works as a blanket ignore (<a href="https://youtrack.jetbrains.com/issue/PY-90265" target="_blank" rel="noopener">PY-90265</a>).</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Completion and auto-import</h2>



<h3 class="wp-block-heading">Smarter auto-import&nbsp;</h3>



<p>Auto-import is now noticeably less noisy. Previously, if a module was already imported, PyCharm would offer to add a second, redundant import instead of qualifying through the one you already had. The quick-fix – and the completion popup – prefer to reuse the existing import.</p>



<p>Given <code>pkg/src.py</code> containing <code>MyClass</code>, and a file that already imports the module, <em>Alt</em>+<em>Enter</em> produces this:</p>



<pre class="EnlighterJSRAW">from pkg import src&nbsp; # no longer flagged as unused

src.MyClass</pre>



<p>instead of adding <code>from pkg.src import MyClass</code>. The same reuse logic applies to plain <code>import pkg.src</code>, and to the auto-import completion on a second <em>Ctrl</em>+<em>Space</em>.</p>



<p>Nested classes can be auto-imported too, which is something PyCharm didn&#8217;t previously support:</p>



<pre class="EnlighterJSRAW"># mod.py

class Outer:

&nbsp;&nbsp;&nbsp;&nbsp;class Inner:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pass

# main.py – Alt+Enter on Inner now offers &quot;Import Outer from mod&quot;

from mod import Outer

value = Outer.Inner()</pre>



<p>(<a href="https://youtrack.jetbrains.com/issue/PY-87970" target="_blank" rel="noopener">PY-87970</a>,<a href="https://youtrack.jetbrains.com/issue/PY-87971" target="_blank" rel="noopener"> PY-87971</a>,<a href="https://youtrack.jetbrains.com/issue/PY-87972" target="_blank" rel="noopener"> PY-87972</a>,<a href="https://youtrack.jetbrains.com/issue/PY-88009" target="_blank" rel="noopener"> PY-88009</a>,<a href="https://youtrack.jetbrains.com/issue/PY-88016" target="_blank" rel="noopener"> PY-88016</a>)</p>



<h3 class="wp-block-heading">Completion for <code>unittest.mock.patch()</code> targets</h3>



<p>Patching by string target previously offered no code assistance, so dotted paths had to be entered manually. The string argument to <code>mock.patch(...)</code> gets code completion for modules, classes, and their attributes, and it no longer suggests the invalid <code>as</code> keyword mid-path:</p>



<pre class="EnlighterJSRAW">from unittest import mock

# sample.py defines: class Foo: my_attr = 42

with mock.patch(&quot;sample.Foo.my_attr&quot;, 14):

&nbsp;&nbsp;&nbsp;&nbsp;...

# completion now offers `sample`, `Foo`, and `my_attr`</pre>



<p>(<a href="https://youtrack.jetbrains.com/issue/PY-89189" target="_blank" rel="noopener">PY-89189</a>,<a href="https://youtrack.jetbrains.com/issue/PY-89191" target="_blank" rel="noopener"> PY-89191</a>,<a href="https://youtrack.jetbrains.com/issue/PY-89192" target="_blank" rel="noopener"> PY-89192</a>)</p>



<h3 class="wp-block-heading">Typed signatures when overriding built-in methods</h3>



<p>Completing an override of a dunder or built-in method fills in the full annotated signature – and auto-imports the types it needs – instead of bare parameters:</p>



<pre class="EnlighterJSRAW">from types import TracebackType

class A:

&nbsp;&nbsp;&nbsp;&nbsp;def __exit__(self, exc_type: type&#091;BaseException] | None,

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exc_val: BaseException | None,

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exc_tb: TracebackType | None): ...

# was: def __exit__(self, exc_type, exc_val, exc_tb):</pre>



<p>(<a href="https://youtrack.jetbrains.com/issue/PY-79218" target="_blank" rel="noopener">PY-79218</a>)</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Editor and inspections</h2>



<h3 class="wp-block-heading">Type inlay hints</h3>



<p>Inferred type arguments are shown inline at the call site, so you can see what a generic resolved to without hovering over it:</p>



<pre class="EnlighterJSRAW">class A&#091;T]:

&nbsp;&nbsp;&nbsp;&nbsp;def __init__(self, t: T): ...

A&#091;int](1) &nbsp; &nbsp; # &#091;int] shown as an inlay hint</pre>



<p>Type names rendered inside inlay hints – return types and solved arguments alike – are also clickable, so you can jump straight to a type&#8217;s definition from the hint.</p>



<p>(<a href="https://youtrack.jetbrains.com/issue/PY-90411" target="_blank" rel="noopener">PY-90411</a>,<a href="https://youtrack.jetbrains.com/issue/PY-90293" target="_blank" rel="noopener"> PY-90293</a>)</p>



<h3 class="wp-block-heading"><code>f-string</code> format-spec validation</h3>



<p>PyCharm already validated the <code>str.format()</code> mini-language. Those checks apply to <code>f-strings</code> too, and PyCharm flags formatting a type that doesn&#8217;t implement <code>__format__</code>:</p>



<pre class="EnlighterJSRAW">data = 1

f&quot;{data:.2f}&quot; &nbsp; # ok

f&quot;{data:.2q}&quot; &nbsp; # now flagged: unsupported format spec

class A: ...

f&quot;{A():d}&quot;&nbsp; &nbsp; &nbsp; # now flagged: A doesn&#039;t support the &#039;d&#039; format</pre>



<p>(<a href="https://youtrack.jetbrains.com/issue/PY-51322" target="_blank" rel="noopener">PY-51322</a>,<a href="https://youtrack.jetbrains.com/issue/PY-89760" target="_blank" rel="noopener"> PY-89760</a>)</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Refactoring</h2>



<p>The <em>Rename</em> refactoring also updates references to a module when the module itself is renamed. Previously, the renaming left importing sites pointing at the old name:</p>



<pre class="EnlighterJSRAW"># rename provider/provider_module.py → some_module.py

from ..provider import provider_module&nbsp; # this reference is updated too</pre>



<p>(<a href="https://youtrack.jetbrains.com/issue/PY-53274" target="_blank" rel="noopener">PY-53274</a>)</p>



<p>The <em>Refactor | Field action</em> is now <em>Attribute</em>, and the documentation says &#8220;instance attributes&#8221; to match Python terminology (<a href="https://youtrack.jetbrains.com/issue/PY-85828" target="_blank" rel="noopener">PY-85828</a>).</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Conclusion</h2>



<p>Taken together, these changes make PyCharm’s understanding of Python more precise and predictable: fewer false positives, better type inference, smarter completion, and less time spent working around cases where the IDE gets valid code wrong.</p>



<p>Many of these improvements started with real-world examples reported by users. If PyCharm still misunderstands a typing pattern, framework API, or other valid Python code in your project, let us know in YouTrack – a small reproducer can help us turn that friction into the next fix.</p>



<p>Try <a href="https://www.jetbrains.com/pycharm/" target="_blank" rel="noopener">PyCharm 2026.2</a> and let us know which improvements make the biggest difference for your workflow.</p>



<p>Thank you for using PyCharm!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Hybrid and Local AI course at DeepLearning.AI</title>
		<link>https://blog.jetbrains.com/pycharm/2026/08/hybrid-and-local-ai-course-at-deeplearning-ai/</link>
		
		<dc:creator><![CDATA[Paul Everitt]]></dc:creator>
		<pubDate>Thu, 13 Aug 2026 10:01:32 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/08/PC-social-BlogFeatured-1280x720-1.png</featuredImage>		<product ><![CDATA[education]]></product>
		<category><![CDATA[learning-courses]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[ai]]></category>
		<category><![CDATA[local-ai]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=pycharm&#038;p=730368</guid>

					<description><![CDATA[Open weight models are having a moment, driven by control, choice, and cost. Hybrid and local AI are now getting serious looks, so JetBrains teamed up with DeepLearning.AI on a free AI Coding Workflows: Hybrid to Local course that covers the ideas and options. The course is now available and uses PyCharm and its AI [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Open weight models are having a moment, driven by control, choice, and cost. Hybrid and local AI are now getting serious looks, so JetBrains teamed up with <a href="https://www.deeplearning.ai" target="_blank" rel="noopener">DeepLearning.AI</a> on a free <a href="https://learn.deeplearning.ai/courses/ai-coding-workflows-from-cloud-to-local/lesson/napfi1/introduction" target="_blank" rel="noopener">AI Coding Workflows: Hybrid to Local</a> course that covers the ideas and options.</p>



<p>The course is now available and uses <a href="https://www.jetbrains.com/pycharm/" data-type="link" data-id="https://www.jetbrains.com/pycharm/" target="_blank" rel="noopener">PyCharm</a> and its AI Chat. Here’s a peek into the course.</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Take back control of your AI coding workflow" src="https://www.youtube.com/embed/xUXJuPC7gz0?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<h2 class="wp-block-heading">Claude Code: Subagents and cheaper models</h2>



<p>We start the course with, well, not-local. Instead, we use what you already know – Claude Code and its Anthropic models – to introduce some of the techniques and “levers” that help bring choice, control, and even cost reduction. (Yes, I wrote emdashes.)</p>



<p>We did a previous course on <a href="https://www.deeplearning.ai/courses/spec-driven-development-with-coding-agents" target="_blank" rel="noopener">Spec-Driven Development</a> (SDD) so of course, we wanted to start there. Smaller models struggle with big, open-ended “vibe coding.” Dividing and bounding the work keeps smaller models on track. Important note: this course’s example app is <em>really</em> basic. You might say “that’s too easy.” But that’s part of the takeaway: big brain models can do the upfront work, forming right-sized steps for smaller models.</p>



<p>We then illustrate this division with a Claude Code <em>subagent</em>. The main chat prompt implements each roadmap phase in a fresh subagent, to better manage context. This then gives the payoff: a cheaper model for the implementer. Use a “big brain” (Opus) for main conversation thinking and a “little brain” (Haiku) for implementation.</p>



<p>Each lesson finishes with metrics about the change in tokens, turns, cost, and estimated wall time. Which brings us to the main course goal: learning the <em>ideas</em> instead of the specifics, which change weekly.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/metrics.png" alt="" class="wp-image-730947"/></figure>



<h2 class="wp-block-heading">New agent, inference, and model</h2>



<p>That covers the four levers:</p>



<ul class="wp-block-list">
<li>Specs shaped for the model size</li>



<li>Specialist subagents to divide work</li>



<li>Cheaper models for the routine work</li>



<li>Collect metrics as evidence to guide thinking</li>
</ul>



<p><br>The course then introduces choice and control:</p>



<ul class="wp-block-list">
<li>New agent: OpenCode</li>



<li>New inference router: OpenRouter</li>



<li>New model and inference host: DeepSeek (via OpenRouter) by moving to a new agent (OpenCode) using inference routing (OpenRouter) to inference hosting and models (DeepSeek)</li>
</ul>



<p><br>We first move to OpenCode, running in PyCharm. JetBrains wants our IDEs to be <em>open platforms</em> for agents and models. This makes the move from Claude Code to OpenCode straightforward: it’s the same UI. We add OpenRouter (a paid step), connect it to OpenCode, and choose DeepSeek as a model.</p>



<p>Next we repeat our sequence: all in one chat, then context isolation using a subagent. But this time, with a different agent and model.</p>



<p>We finish by making a dedicated implementer subagent in Markdown. This gives quite a number of levers of control: in the frontmatter for mandatory controls, and in the subagent body for “persuasion” guidance. Most importantly, we have the implementer use the smaller DeepSeek v4 Flash model as the “little brain.”</p>



<p>Compared to the Claude Code version, the metrics were, unsurprisingly, a lot cheaper.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/openrouter.png" alt="" class="wp-image-730958"/></figure>



<h2 class="wp-block-heading">Hybrid and Local</h2>



<p>Now for the main attraction: for routine development, can we do some – or even all – of the work locally?</p>



<p>We start with a lesson on setting up local AI: LM Studio as the inference server and Gemma 4 12B as the local model, targeting a 32 GB laptop.</p>



<p>We then configure the implementer subagent to use this local Gemma 4 model, promoting DeepSeek v4 Flash from last lesson’s “little brain” up to “big brain.” The results? Quite good, as it turns out.</p>



<p>Then the big test: fully local, with Qwen 3.5 27B as the “big brain.” The results: better than expected, showing that guardrails help.</p>



<p>How did hybrid and local do? Both of these lessons finish with a review of the metrics. That’s one of the big course takeaways: look at the evidence. You can see how small models struggle, and see the effect of helping them succeed.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/lmstudio.png" alt="" class="wp-image-730969"/></figure>



<h2 class="wp-block-heading">Hybrid and Local AI Are Heating Up</h2>



<p>Much thanks to <a href="http://deeplearning.ai/" target="_blank" rel="noopener">DeepLearning.AI</a> both for working with us again and for pushing to get this out fast. This topic is now red-hot in the news: Sovereign AI, privacy and security, and of course cost. The innovations are coming really fast and it is important to have a gentle introduction to the fundamentals.</p>



<p>We’ll do more updates here on Local AI for control, choice, and cost. Most of all, we at PyCharm believe in the human-in-the-loop. Stay tuned for more on this.</p>


    <div class="buttons">
        <div class="buttons__row">
                                                <a href="https://learn.deeplearning.ai/courses/ai-coding-workflows-from-cloud-to-local/lesson/napfi1/introduction" class="btn" target="" rel="noopener">Enroll for free</a>
                                                    </div>
    </div>




]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>What&#8217;s New in PyCharm 2026.2.1</title>
		<link>https://blog.jetbrains.com/pycharm/2026/08/what-s-new-in-pycharm-2026-2-1/</link>
		
		<dc:creator><![CDATA[Evgenia Verbina]]></dc:creator>
		<pubDate>Wed, 12 Aug 2026 12:05:32 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/08/PC-releases-BlogFeatured-1280x720-1.png</featuredImage>		<category><![CDATA[releases]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=pycharm&#038;p=727409</guid>

					<description><![CDATA[This PyCharm release is a big one for anyone building with AI. Your agents can now roll up their sleeves inside your Jupyter notebooks – working against a live kernel instead of firing off disconnected scripts. And they finally know which Python to use, so packages land in the right environment every time. We&#8217;re also [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>This <a href="https://www.jetbrains.com/pycharm/" data-type="link" data-id="https://www.jetbrains.com/pycharm/" target="_blank" rel="noopener">PyCharm</a> release is a big one for anyone building with AI. Your agents can now roll up their sleeves inside your Jupyter notebooks – working against a live kernel instead of firing off disconnected scripts. And they finally know which Python to use, so packages land in the right environment every time.</p>



<p>We&#8217;re also welcoming marimo notebooks into the IDE and introducing changes to bundled plugins to keep PyCharm fast and focused.</p>



<h2 class="wp-block-heading">Release highlights</h2>



<h3 class="wp-block-heading">Jupyter notebook skill for AI agents</h3>



<p>Let AI agents such as Claude Code and Codex create, edit, and run <code>.ipynb</code> notebooks via PyCharm&#8217;s notebook model and a live kernel, so variables, models, and data persist across cells instead of disappearing when the agent shells out. For you, this means more reliable notebook and ML work – with fewer tokens used. To start, just open the AI chat and ask the agent to work in your notebook.</p>


    <div class="buttons">
        <div class="buttons__row">
                                                <a href="https://blog.jetbrains.com/pycharm/2026/08/we-gave-ai-agents-a-live-jupyter-kernel-in-pycharm/" class="btn" target="">Learn more</a>
                                                    </div>
    </div>







<h3 class="wp-block-heading">Agent environment coordinator</h3>



<p>Tired of AI agents installing packages into the wrong Python environment? This new skill gives the agent your project&#8217;s configured interpreter and tool – <code>uv</code>, Poetry, <code>pip</code> in a <code>venv</code>, or <code>conda</code> – so commands target the right environment, not a system one. If none exists, it can set one up via PyCharm, and the agent decides how to use the information. To start, ask the agent to run or install something in your project.</p>


    <div class="buttons">
        <div class="buttons__row">
                                                <a href="https://blog.jetbrains.com/pycharm/2026/08/we-stopped-ai-agents-from-installing-into-the-wrong-python-task-success-rates-jumped-to-95/" class="btn" target="">Learn more</a>
                                                    </div>
    </div>







<h3 class="wp-block-heading">marimo notebooks in PyCharm [third-party plugin]</h3>



<p>You can now open, edit, and run marimo notebooks directly in PyCharm with the new plugin developed by the marimo team.&nbsp;</p>



<p>Work with reactive cells and interactive UI elements in a dedicated notebook without leaving your IDE. Because marimo notebooks are stored as Python files, they are Git-friendly, executable as scripts, and easy to integrate into your existing Python projects.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/07/image-51.png" alt="" class="wp-image-727410"/></figure>


    <div class="buttons">
        <div class="buttons__row">
                                                <a href="https://plugins.jetbrains.com/plugin/32416-marimo" class="btn" target="" rel="noopener">Install the plugin</a>
                                                    </div>
    </div>







<h3 class="wp-block-heading">Changes to bundled plugins in 2026.2</h3>



<p>As part of ongoing maintenance, we are unbundling and deprecating low-usage plugins, including Data Wrangler, Hugging Face, and Google Colab support. You can continue to install compatible versions from JetBrains Marketplace, but these plugins are no longer bundled or actively maintained by the PyCharm team. A more focused set of bundled plugins means a leaner codebase, helping us keep PyCharm fast and responsive and invest our effort where it has the most impact.</p>


    <div class="buttons">
        <div class="buttons__row">
                                                <a href="https://blog.jetbrains.com/pycharm/2026/08/unbundling-and-deprecating-low-usage-plugins-in-pycharm/" class="btn" target="">Learn more</a>
                                                    </div>
    </div>







<h2 class="wp-block-heading">Redesigned Python Packages tool window</h2>



<ul class="wp-block-list">
<li>Packages now appear in a collapsible tree alongside their dependencies so you can see what&#8217;s installed and why – with new icons, right-aligned versions, and inline Install/Update links.</li>



<li>A new floating search popup (think “Search Everywhere” but for packages) makes finding and installing fast. It also shows you which environment will be used and lets you pick a module and dependency group.</li>



<li>You can install a package into specific <code>uv</code>/Poetry dependency groups like dev or test per workspace member, change versions inline or through the new Change Version dialog, and install from VCS via Custom Installation.</li>



<li>Package repositories can be enabled or disabled, with state remembered across sessions. In addition, unreachable URLs show a clear error, and Remote Development support is substantially improved.</li>
</ul>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/PY-89838-Python-Packages-Tool-Window-redesign.png" alt="Redesigned Python Packages tool window in PyCharm" class="wp-image-730282"/></figure>



<h2 class="wp-block-heading">Clearer type checking</h2>



<p>Get clearer, more actionable type messages:</p>



<ul class="wp-block-list">
<li>Richer type-mismatch errors, now with a breakdown of why the types don&#8217;t match. </li>



<li>A type diff for callables and other composite types, so both sides read the same way. </li>



<li>Fully rendered names and types in inspection tooltips, with clickable links. </li>
</ul>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/PY-80221-explain_Show-a-breakdown-when-type-mismatch-is-reported.png" alt="Clearer type checking in PyCharm" class="wp-image-730293"/></figure>



<h2 class="wp-block-heading">Bug fixes</h2>



<ul class="wp-block-list">
<li><strong>Virtual environments for end-of-life Python</strong>: PyCharm no longer creates venvs for Python 2.7, 3.6, and 3.7. You can still create a new env from a command line and add it to the IDE manually.</li>



<li><strong>SQLAlchemy 2.0 Session.get() inference</strong>: <code>Session.get(Entity, id)</code> (and SQLModel) is now inferred as a model instance rather than the class.</li>
</ul>



<h2 class="wp-block-heading">Download PyCharm</h2>



<p>All of these updates are available in PyCharm 2026.2.1. Update right from the IDE or the Toolbox App, or <a href="https://www.jetbrains.com/pycharm/download/" target="_blank" rel="noopener">download the latest version</a> to try everything out on your own projects. As always, we’d love to hear your feedback.</p>


    <div class="buttons">
        <div class="buttons__row">
                                                <a href="https://www.jetbrains.com/pycharm/download/" class="btn" target="" rel="noopener">Download PyCharm</a>
                                                    </div>
    </div>







<p></p>
]]></content:encoded>
					
		
		
		                    <language>
                        <code><![CDATA[zh-hans]]></code>
                        <url>https://blog.jetbrains.com/zh-hans/pycharm/2026/08/what-s-new-in-pycharm-2026-2-1/</url>
                    </language>
                                    <language>
                        <code><![CDATA[pt-br]]></code>
                        <url>https://blog.jetbrains.com/pt-br/pycharm/2026/08/what-s-new-in-pycharm-2026-2-1/</url>
                    </language>
                                    <language>
                        <code><![CDATA[ko]]></code>
                        <url>https://blog.jetbrains.com/ko/pycharm/2026/08/what-s-new-in-pycharm-2026-2-1/</url>
                    </language>
                                    <language>
                        <code><![CDATA[ja]]></code>
                        <url>https://blog.jetbrains.com/ja/pycharm/2026/08/what-s-new-in-pycharm-2026-2-1/</url>
                    </language>
                                    <language>
                        <code><![CDATA[fr]]></code>
                        <url>https://blog.jetbrains.com/fr/pycharm/2026/08/what-s-new-in-pycharm-2026-2-1/</url>
                    </language>
                                    <language>
                        <code><![CDATA[es]]></code>
                        <url>https://blog.jetbrains.com/es/pycharm/2026/08/what-s-new-in-pycharm-2026-2-1/</url>
                    </language>
                                    <language>
                        <code><![CDATA[de]]></code>
                        <url>https://blog.jetbrains.com/de/pycharm/2026/08/what-s-new-in-pycharm-2026-2-1/</url>
                    </language>
                	</item>
		<item>
		<title>We Stopped AI Agents From Installing Into the Wrong Python: Task Success Rates Jumped to 95%+</title>
		<link>https://blog.jetbrains.com/pycharm/2026/08/we-stopped-ai-agents-from-installing-into-the-wrong-python-task-success-rates-jumped-to-95/</link>
		
		<dc:creator><![CDATA[Evgenia Verbina]]></dc:creator>
		<pubDate>Wed, 12 Aug 2026 12:01:07 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/08/PC-releases-BlogFeatured-1280x720-1-3.png</featuredImage>		<category><![CDATA[releases]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=pycharm&#038;p=730210</guid>

					<description><![CDATA[AI agents are supposed to save you time. Ask one to install a dependency or run your project, though, and it often does the opposite: It installs into the wrong Python, ignores the uv or virtual environment your project uses, and hands back a broken setup for you to fix yourself. PyCharm’s new Agent Environment [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>AI agents are supposed to save you time. Ask one to install a dependency or run your project, though, and it often does the opposite: It installs into the wrong Python, ignores the uv or virtual environment your project uses, and hands back a broken setup for you to fix yourself.</p>



<p><a href="https://www.jetbrains.com/pycharm/" target="_blank" rel="noopener">PyCharm</a>’s new Agent Environment Coordinator skill fixes this, and this blog post shows just how helpful it proves to be.</p>



<figure style="margin: 28px 0;">
  <svg viewBox="0 0 780 220" role="img" aria-label="Opener visualization for the Agent Environment Coordinator skill. Average task success improved from 68 percent at baseline to 98 percent with the skill, across 28 Python tasks and 6 AI models, while avoiding system Python pollution." style="display:block;width:100%;height:auto;max-width:780px;">
    <rect x="0" y="0" fill="#ffffff"/>
    <rect x="18" y="18" fill="#ffffff" stroke="#d1d5db" rx="6"/>

    <text x="42" y="52" font-size="12" font-weight="700" fill="#6b7280">AGENT ENVIRONMENT COORDINATOR</text>
    <text x="42" y="82" font-size="24" font-weight="750" fill="#111827">The agent stopped guessing Python.</text>

    <text x="44" y="116" font-size="15" font-weight="700" fill="#374151">Average task success</text>
    <text x="42" y="170" font-size="50" font-weight="800" fill="#111827">68%</text>
    <text x="170" y="168" font-size="24" font-weight="700" fill="#9ca3af">-&gt;</text>
    <text x="228" y="170" font-size="50" font-weight="800" fill="#16a34a">98%</text>
    <text x="44" y="194" font-size="12" font-weight="700" fill="#6b7280">Baseline</text>
    <text x="230" y="194" font-size="12" font-weight="700" fill="#047857">With skill</text>

    <rect x="482" y="48" fill="#f8fafc" stroke="#e5e7eb" rx="6"/>
    <text x="504" y="72" font-size="22" font-weight="800" fill="#111827">28</text>
    <text x="504" y="91" font-size="12" fill="#6b7280">Python tasks</text>

    <rect x="610" y="48" fill="#f8fafc" stroke="#e5e7eb" rx="6"/>
    <text x="632" y="72" font-size="22" font-weight="800" fill="#111827">6</text>
    <text x="632" y="91" font-size="12" fill="#6b7280">AI models</text>

    <rect x="482" y="118" fill="#ecfdf5" stroke="#bbf7d0" rx="6"/>
    <circle cx="508" cy="141" r="8" fill="#16a34a"/>
    <path d="M504 141 L507 144 L513 137" fill="none" stroke="#ffffff" stroke- stroke-linecap="round" stroke-linejoin="round"/>
    <text x="528" y="145" font-size="13" font-weight="700" fill="#047857">No system Python pollution</text>
  </svg>
</figure>



<p>We tested six AI models using 28 different Python programming tasks. Without access to the project&#8217;s real environment, they solved 68% of the tasks on average. After we gave them access, their average success rate shot up to 98% – and they didn’t even modify the system Python.</p>



<p>If you’re currently using AI agents in your Python projects, read on to see how the Agent Environment Coordinator can improve their performance.</p>



<h2 class="wp-block-heading">When the agent could see the project&#8217;s environment, it stopped failing</h2>



<p>When using the Agent Environment Coordinator skill, each agent, regardless of the model, was able to complete far more of the 28 tasks. (See the Methodology section below for details on what the tasks entailed.) Here is the share of successfully completed tasks for each model, comparing the baseline to running with the skill in PyCharm:</p>



<figure style="margin: 24px 0;">
  <svg viewBox="0 0 780 330" role="img" aria-label="Model success rates without and with the Agent Environment Coordinator skill. Claude Sonnet 4.6: 36 percent to 96 percent. Claude Sonnet 5: 73 percent to 100 percent. Claude Opus 4.8: 67 percent to 100 percent. Claude Opus 5.0: 94 percent to 98 percent. Codex GPT-5.5: 62 percent to 95 percent. Codex GPT-5.6: 80 percent to 100 percent." style="display:block;width:100%;height:auto;max-width:780px;">
    <rect x="0" y="0" fill="#ffffff"/>
    <text x="24" y="28" font-size="11" font-weight="700" fill="#6b7280">MODEL</text>
    <text x="292" y="28" font-size="11" font-weight="700" fill="#6b7280">BASELINE</text>
    <text x="535" y="28" font-size="11" font-weight="700" fill="#6b7280">WITH SKILL</text>
    <line x1="20" y1="44" x2="760" y2="44" stroke="#d1d5db"/>
    <line x1="20" y1="90" x2="760" y2="90" stroke="#e5e7eb"/>
    <line x1="20" y1="136" x2="760" y2="136" stroke="#e5e7eb"/>
    <line x1="20" y1="182" x2="760" y2="182" stroke="#e5e7eb"/>
    <line x1="20" y1="228" x2="760" y2="228" stroke="#e5e7eb"/>
    <line x1="20" y1="274" x2="760" y2="274" stroke="#e5e7eb"/>
    <line x1="20" y1="320" x2="760" y2="320" stroke="#d1d5db"/>
    <text x="24" y="73" font-size="14" font-weight="700" fill="#111827">Claude Sonnet 4.6</text>
    <rect x="292" y="60" fill="#f3f4f6" rx="3"/>
    <rect x="292" y="60" fill="#6b7280" rx="3"/>
    <text x="452" y="73" font-size="13" font-weight="700" fill="#111827">36%</text>
    <rect x="535" y="60" fill="#f3f4f6" rx="3"/>
    <rect x="535" y="60" fill="#16a34a" rx="3"/>
    <text x="695" y="73" font-size="13" font-weight="700" fill="#111827">96%</text>
    <text x="24" y="119" font-size="14" font-weight="700" fill="#111827">Claude Sonnet 5</text>
    <rect x="292" y="106" fill="#f3f4f6" rx="3"/>
    <rect x="292" y="106" fill="#6b7280" rx="3"/>
    <text x="452" y="119" font-size="13" font-weight="700" fill="#111827">73%</text>
    <rect x="535" y="106" fill="#f3f4f6" rx="3"/>
    <rect x="535" y="106" fill="#16a34a" rx="3"/>
    <text x="695" y="119" font-size="13" font-weight="700" fill="#111827">100%</text>
    <text x="24" y="165" font-size="14" font-weight="700" fill="#111827">Claude Opus 4.8</text>
    <rect x="292" y="152" fill="#f3f4f6" rx="3"/>
    <rect x="292" y="152" fill="#6b7280" rx="3"/>
    <text x="452" y="165" font-size="13" font-weight="700" fill="#111827">67%</text>
    <rect x="535" y="152" fill="#f3f4f6" rx="3"/>
    <rect x="535" y="152" fill="#16a34a" rx="3"/>
    <text x="695" y="165" font-size="13" font-weight="700" fill="#111827">100%</text>
    <text x="24" y="211" font-size="14" font-weight="700" fill="#111827">Claude Opus 5.0</text>
    <rect x="292" y="198" fill="#f3f4f6" rx="3"/>
    <rect x="292" y="198" fill="#6b7280" rx="3"/>
    <text x="452" y="211" font-size="13" font-weight="700" fill="#111827">94%</text>
    <rect x="535" y="198" fill="#f3f4f6" rx="3"/>
    <rect x="535" y="198" fill="#16a34a" rx="3"/>
    <text x="695" y="211" font-size="13" font-weight="700" fill="#111827">98%</text>
    <text x="24" y="257" font-size="14" font-weight="700" fill="#111827">Codex / GPT-5.5</text>
    <rect x="292" y="244" fill="#f3f4f6" rx="3"/>
    <rect x="292" y="244" fill="#6b7280" rx="3"/>
    <text x="452" y="257" font-size="13" font-weight="700" fill="#111827">62%</text>
    <rect x="535" y="244" fill="#f3f4f6" rx="3"/>
    <rect x="535" y="244" fill="#16a34a" rx="3"/>
    <text x="695" y="257" font-size="13" font-weight="700" fill="#111827">95%</text>
    <text x="24" y="303" font-size="14" font-weight="700" fill="#111827">Codex / GPT-5.6</text>
    <rect x="292" y="290" fill="#f3f4f6" rx="3"/>
    <rect x="292" y="290" fill="#6b7280" rx="3"/>
    <text x="452" y="303" font-size="13" font-weight="700" fill="#111827">80%</text>
    <rect x="535" y="290" fill="#f3f4f6" rx="3"/>
    <rect x="535" y="290" fill="#16a34a" rx="3"/>
    <text x="695" y="303" font-size="13" font-weight="700" fill="#111827">100%</text>
  </svg>
</figure>



<p>Every model improved, with the weakest baseline improving the most.</p>



<h2 class="wp-block-heading">Why we built this</h2>



<p>LLMs almost never use a project&#8217;s dedicated virtual environment. They fall back to a system interpreter, ignoring the fact that there may be several system interpreters and real projects often have more complex, multi-interpreter setups already configured in PyCharm that the agent has no way to see.</p>



<p>For example, <code>pip install httpx</code> runs against the wrong Python, the package installs globally, the script fails, and the environment is polluted.</p>



<p>PyCharm already knows which interpreter belongs to your project and which tool manages it. The agent just couldn’t ask – so we gave it a way.</p>



<h2 class="wp-block-heading">How it works</h2>



<p>The Agent Environment Coordinator lets the agent ask PyCharm two things. <code>get_python_environment</code> returns the correct interpreter for the file or module in question – the path plus the tool behind it (<code>uv</code>, Poetry, <code>pip</code> + venv, conda). If no environment exists yet, <code>configure_python_interpreter</code> sets one up by reusing PyCharm&#8217;s existing configuration mechanism – the same one that offers to create a <code>.venv</code> – so the new interpreter also becomes visible in the IDE.</p>



<p>The important part is what the skill <em>doesn&#8217;t </em>do. It returns information; it never intercepts or rewrites the command. The agent asks which Python to use, gets an accurate answer, and decides whether and how to use it to write the command itself. We hand it the missing context using existing mechanisms in PyCharm – we don&#8217;t let it take the wheel.</p>



<p>The payoff is practical: The agent works with your project setup out of the box. You don’t need to coach it through prompts about which environment to use, or clean up wrong installs afterward.</p>



<h2 class="wp-block-heading">Methodology</h2>



<p>We built a dataset of 28 tasks covering everyday Python-environment work, like running tests, installing a library, listing dependencies, resolving a version conflict, and so forth.</p>



<p>Each task ultimately required the agent to pick the correct interpreter to execute a command. The eval also reduced the reward when the agent polluted the system environment, so a high score reflects a clean run, not just a passing one.</p>



<p>We ran the full set three times per model, with and without the skill, using <a href="https://www.harborframework.com/" target="_blank" rel="noopener">Harbor</a>, and averaged the results.</p>



<h2 class="wp-block-heading">Results</h2>



<p>Success rates climbed across the board – Sonnet 5 improved from 73% to 100%, Opus 5 from 94% to 100%, and Codex/GPT-5.6 from 80% to 100%.&nbsp;</p>



<p>Two things stand out in addition to this numerical jump:&nbsp;</p>



<ul class="wp-block-list">
<li>The improved success rates demonstrate that the models lacked context, rather than being incapable of completing the tasks. The models didn&#8217;t get better – they just stopped guessing the interpreter, which is why the weakest baseline improved the most.</li>



<li>Because the eval docks points for polluting the system environment, these higher scores also imply cleaner runs. The agents didn&#8217;t just pass more often; they stopped leaving a mess behind.</li>
</ul>



<h2 class="wp-block-heading">Want to try it?</h2>



<p>Open the AI chat in <a href="https://www.jetbrains.com/pycharm/download/" data-type="link" data-id="https://www.jetbrains.com/pycharm/download/" target="_blank" rel="noopener">PyCharm 2026.2.1</a> and ask your agent to install a package or run something in your project – it&#8217;ll reach for the right interpreter on its own.</p>



<p>The Agent Environment Coordinator is one of PyCharm&#8217;s bundled skills. You can browse and manage all of them right in the IDE, expand the built-in library with external registries like public GitHub repositories, or import skills you&#8217;ve already set up for Claude Code or Codex.</p>



<figure class="wp-block-video"><video controls src="https://blog.jetbrains.com/wp-content/uploads/2026/08/skillsManager.mp4"></video></figure>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>We Gave AI Agents a Live Jupyter Kernel in PyCharm</title>
		<link>https://blog.jetbrains.com/pycharm/2026/08/we-gave-ai-agents-a-live-jupyter-kernel-in-pycharm/</link>
		
		<dc:creator><![CDATA[Evgenia Verbina]]></dc:creator>
		<pubDate>Wed, 12 Aug 2026 12:00:34 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/08/PC-releases-BlogFeatured-1280x720-1-2.png</featuredImage>		<category><![CDATA[releases]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=pycharm&#038;p=730172</guid>

					<description><![CDATA[If you&#8217;ve handed notebook work to an AI agent, you know how it tends to go: More often than not, it corrupts your .ipynb, loses your trained model the moment the run finishes, or burns budget sitting idle through a long job while you watch. To solve this, we’re introducing a brand-new Jupyter skill. Built [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>If you&#8217;ve handed notebook work to an AI agent, you know how it tends to go: More often than not, it corrupts your <code>.ipynb</code>, loses your trained model the moment the run finishes, or burns budget sitting idle through a long job while you watch.</p>



<p>To solve this, we’re introducing a brand-new Jupyter skill. Built directly into <a href="https://www.jetbrains.com/pycharm/" target="_blank" rel="noopener">PyCharm,</a> it lets your AI agent work inside a live Jupyter kernel instead of handing the job to a subprocess and losing your progress. This one change means state persists across cells, the <code>.ipynb</code> isn&#8217;t corrupted, and long jobs wait until execution is completed instead of constantly checking and wasting precious tokens.</p>



<figure style="margin: 28px 0;">
  <svg viewBox="0 0 780 280" role="img" aria-label="Opener visualization for the Jupyter skill. Claude Opus 5 ran 12 percent cheaper through the live kernel than through the shell: USD 59.09 versus USD 67.06 across 12 machine learning tasks. Kernel mode had 98 percent cache reads, and state persists across cells." style="display:block;width:100%;height:auto;max-width:780px;">
    <rect x="0" y="0" fill="#ffffff"/>
    <rect x="18" y="18" fill="#ffffff" stroke="#d1d5db" rx="6"/>

    <text x="42" y="52" font-size="12" font-weight="700" fill="#6b7280">JUPYTER SKILL FOR PYCHARM</text>
    <text x="42" y="82" font-size="24" font-weight="750" fill="#111827">A live kernel made Opus</text>
    <text x="42" y="111" font-size="24" font-weight="750" fill="#111827">cheaper than the shell.</text>

    <text x="42" y="170" font-size="50" font-weight="800" fill="#16a34a">12%</text>
    <text x="153" y="170" font-size="50" font-weight="800" fill="#16a34a">cheaper</text>
    <text x="44" y="194" font-size="13" fill="#6b7280">Claude Opus 5 across 12 ML tasks</text>

    <rect x="42" y="216" fill="#f3f4f6" rx="3"/>
    <rect x="42" y="216" fill="#16a34a" rx="3"/>
    <text x="42" y="246" font-size="12" font-weight="700" fill="#047857">Kernel</text>
    <text x="96" y="246" font-size="12" fill="#047857">USD 59.09</text>

    <rect x="362" y="216" fill="#f3f4f6" rx="3"/>
    <rect x="362" y="216" fill="#6b7280" rx="3"/>
    <text x="362" y="246" font-size="12" font-weight="700" fill="#374151">Shell</text>
    <text x="411" y="246" font-size="12" fill="#6b7280">USD 67.06</text>

    <rect x="502" y="48" fill="#f8fafc" stroke="#e5e7eb" rx="6"/>
    <text x="520" y="72" font-size="22" font-weight="800" fill="#111827">12</text>
    <text x="520" y="91" font-size="12" fill="#6b7280">ML tasks</text>

    <rect x="612" y="48" fill="#ecfdf5" stroke="#bbf7d0" rx="6"/>
    <text x="632" y="72" font-size="22" font-weight="800" fill="#16a34a">98%</text>
    <text x="632" y="91" font-size="12" fill="#047857">cache reads</text>

    <rect x="502" y="122" fill="#f8fafc" stroke="#e5e7eb" rx="6"/>
    <circle cx="526" cy="145" r="8" fill="#16a34a"/>
    <path d="M522 145 L525 148 L531 141" fill="none" stroke="#ffffff" stroke- stroke-linecap="round" stroke-linejoin="round"/>
    <text x="546" y="149" font-size="13" font-weight="700" fill="#111827">State persists across cells</text>
  </svg>
</figure>



<h2 class="wp-block-heading">For Opus, the kernel ran cheaper than the shell</h2>



<p>We tested the efficiency of the Jupyter skill by comparing the performance of agents when solving twelve different machine learning problems. We compared three different modes: strictly using bash, strictly using the kernel via the Jupyter skill, and a mixture of both.</p>



<p>While the agent was able to solve all twelve tasks in every mode, there was a difference in how much each mode spent. For Claude Opus 5, working through the kernel cost 59.09 USD versus 67.06 USD through the shell – about 12% cheaper.</p>



<figure style="margin: 24px 0;">
  <svg viewBox="0 0 780 170" role="img" aria-label="Table visualization. Kernel: cost USD 59.09, input 72.7M, cache reads 98 percent. Shell: cost USD 67.06, input 36.3M, cache reads 82 percent." style="display:block;width:100%;height:auto;max-width:780px;">
    <rect x="0" y="0" fill="#ffffff"/>
    <text x="24" y="28" font-size="11" font-weight="700" fill="#6b7280">MODE</text>
    <text x="170" y="28" font-size="11" font-weight="700" fill="#6b7280">COST</text>
    <text x="390" y="28" font-size="11" font-weight="700" fill="#6b7280">INPUT TOKENS</text>
    <text x="585" y="28" font-size="11" font-weight="700" fill="#6b7280">CACHE READS</text>
    <line x1="20" y1="44" x2="760" y2="44" stroke="#d1d5db"/>
    <line x1="20" y1="104" x2="760" y2="104" stroke="#e5e7eb"/>
    <line x1="20" y1="164" x2="760" y2="164" stroke="#d1d5db"/>
    <text x="24" y="78" font-size="16" font-weight="700" fill="#111827">Kernel (skill)</text>
    <text x="24" y="138" font-size="16" font-weight="700" fill="#111827">Shell (baseline)</text>
    <rect x="170" y="58" fill="#f3f4f6" rx="3"/>
    <rect x="170" y="58" fill="#16a34a" rx="3"/>
    <text x="170" y="90" font-size="13" font-weight="700" fill="#111827">USD 59.09</text>
    <rect x="170" y="118" fill="#f3f4f6" rx="3"/>
    <rect x="170" y="118" fill="#6b7280" rx="3"/>
    <text x="170" y="150" font-size="13" font-weight="700" fill="#111827">USD 67.06</text>
    <rect x="390" y="58" fill="#f3f4f6" rx="3"/>
    <rect x="390" y="58" fill="#16a34a" rx="3"/>
    <text x="390" y="90" font-size="13" font-weight="700" fill="#111827">72.7M</text>
    <rect x="390" y="118" fill="#f3f4f6" rx="3"/>
    <rect x="390" y="118" fill="#6b7280" rx="3"/>
    <text x="390" y="150" font-size="13" font-weight="700" fill="#111827">36.3M</text>
    <rect x="585" y="58" fill="#f3f4f6" rx="3"/>
    <rect x="585" y="58" fill="#16a34a" rx="3"/>
    <text x="585" y="90" font-size="13" font-weight="700" fill="#111827">98%</text>
    <rect x="585" y="118" fill="#f3f4f6" rx="3"/>
    <rect x="585" y="118" fill="#6b7280" rx="3"/>
    <text x="585" y="150" font-size="13" font-weight="700" fill="#111827">82%</text>
  </svg>
</figure>



<p>Here’s the counterintuitive part: The kernel used more tokens, yet cost less. That&#8217;s because it keeps the prompt cache warm. 98% of its input was cache reads, versus 82% for the shell – and cache reads incur only 1/12 of the cost of creating a fresh cache.</p>



<h2 class="wp-block-heading">Why we built this</h2>



<p>Notebooks are where coding agents tend to fall apart. Most AI tools treat an <code>.ipynb</code> like a plain text file: They hand-edit the JSON (and corrupt it), and then run code by running a subprocess. The moment an agent starts the subprocess, the kernel state – the trained model, the loaded dataframe, and every import – lives in the child process, and vanishes when that process exits. The agent can&#8217;t inspect it, checkpoint it, or reuse it. Output is buffered until the run ends, so progress is invisible, and long training jobs get babysat – blind until the connection times out.</p>



<p>We asked the obvious question: What if the agent operated a live Jupyter kernel through the IDE?</p>



<p>So we built our new Jupyter skill, which exposes PyCharm&#8217;s own notebook intelligence – its notebook model and live-kernel control – to the agent. It does this through a single MCP wrapper, <code>execute_tool</code>, which covers the core notebook operations, including creating, editing, and reading notebooks; running cells; waiting on long runs; probing a running kernel; and controlling its lifecycle. The skill tells the agent when and how to use them.</p>



<h2 class="wp-block-heading">How it works</h2>



<p>The agent:</p>



<ul class="wp-block-list">
<li><strong>Runs directly in the kernel.</strong> The agent writes real Python into a cell and runs it, so variables, models, and data persist across cells – exactly like a human working in a notebook.</li>



<li><strong>Waits instead of polling.</strong> Rather than polling on a fixed timer and re-billing context on every idle call, <code>wait_cell_execution</code> is blocked until the cell finishes (or a safe cap), and then hands control back. This helps reduce idle round-trips.</li>



<li><strong>Reads only what&#8217;s new.</strong> As a long run streams output, the agent reads the <em>delta</em> – just the lines since its last check – instead of re-sending the whole, ever-growing cell output every time.</li>
</ul>



<h2 class="wp-block-heading">Methodology</h2>



<p>We used twelve tasks from the MLGym machine-learning benchmark – classification, regression, and reinforcement-learning problems, each of which requires the agent to load data, train, evaluate, and save a result. We ran them across Claude Opus 5 and OpenAI&#8217;s GPT-5.6 models, Sol and Terra, through Codex. We compared three modes: through the kernel only, through the kernel plus the shell, and through the shell alone. As these benchmark tasks expose test labels to the agent, we treat cost – not accuracy – as the reliable signal.</p>



<p>One caveat, for transparency: An audit found that one of the twelve tasks, Titanic, was contaminated – the agent could peek at the test set, and each agent used this to select the best model to present as the final solution. Titanic is a well-known, easy task for LLMs, and the issue appeared consistently across all three modes, so it doesn&#8217;t skew the comparison. The pattern holds even with Titanic removed – the kernel still ran 10% cheaper than the shell for Opus (56.34 USD versus 62.65 USD).</p>



<h2 class="wp-block-heading">Results</h2>



<p>The cost win is model- and task-dependent. It was clearest for Claude Opus on long, stateful jobs, while the shell came out cheaper on short tasks and for the Codex models – which already use the cache efficiently, so there the skill earns its place on workflow, not cost.</p>



<h2 class="wp-block-heading">Where it still falls short</h2>



<p>Two things are worth keeping in mind:</p>



<ul class="wp-block-list">
<li><strong>Tell the agent to save its artifacts.</strong> In one run, the agent trained a solid model but never saved the submission file before finishing. This is easy to prevent from your side: Just add a clear instruction in your context file (e.g. <code>CLAUDE.md</code>) or a skill so the agent saves any model the moment it clears your target metric.</li>



<li><strong>Some tasks are still beyond agents.</strong> On a hard task, the agent&#8217;s approach simply wasn&#8217;t strong enough to clear the bar. That&#8217;s genuine ML difficulty, not a tooling gap – some complex problems still need a human in the loop.</li>
</ul>



<p>The skill removes the <em>mechanical</em> waste, but doesn&#8217;t turn a weak approach into a strong one.</p>



<h2 class="wp-block-heading">Want to try it?</h2>



<p>Open the AI chat in <a href="https://www.jetbrains.com/pycharm/download/" data-type="link" data-id="https://www.jetbrains.com/pycharm/download/" target="_blank" rel="noopener">PyCharm 2026.2.1</a> and ask your agent to work in a notebook – create one, load a dataset, or kick off a training run. The agent will operate the kernel directly instead of running commands in the shell.</p>



<p>You can also browse and manage skills directly from the IDE, expand the built-in library with external registries like public GitHub repositories, or let PyCharm import skills you’ve already set up for Claude Code or Codex.</p>



<figure class="wp-block-video"><video controls src="https://blog.jetbrains.com/wp-content/uploads/2026/08/skillsManager.mp4"></video></figure>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Unbundling and Deprecating Low-Usage Plugins in PyCharm</title>
		<link>https://blog.jetbrains.com/pycharm/2026/08/unbundling-and-deprecating-low-usage-plugins-in-pycharm/</link>
		
		<dc:creator><![CDATA[Evgenia Verbina]]></dc:creator>
		<pubDate>Wed, 12 Aug 2026 11:59:50 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/08/PC-releases-BlogFeatured-1280x720-1-1.png</featuredImage>		<category><![CDATA[releases]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=pycharm&#038;p=730146</guid>

					<description><![CDATA[As part of ongoing maintenance, we are unbundling and deprecating low-usage plugins starting with PyCharm 2026.2. This includes support for Data Wrangler, Hugging Face, and Google Colab, among others.&#160; A more focused set of bundled plugins means a leaner codebase, enabling us to keep PyCharm fast and responsive and invest our effort where it has [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>As part of ongoing maintenance, we are unbundling and deprecating low-usage plugins starting with <a href="https://www.jetbrains.com/pycharm/" target="_blank" rel="noopener">PyCharm</a> 2026.2. This includes support for Data Wrangler, Hugging Face, and Google Colab, among others.&nbsp;</p>



<p>A more focused set of bundled plugins means a leaner codebase, enabling us to keep PyCharm fast and responsive and invest our effort where it has the most impact.</p>



<p>You can continue installing compatible versions from the <a href="https://plugins.jetbrains.com/" target="_blank" rel="noopener">JetBrains Marketplace</a>, but these plugins will no longer be bundled or actively maintained by the PyCharm team. Read this blog post for the full list, deprecation timeline, and next steps.</p>



<h2 class="wp-block-heading">Why we’re making this change</h2>



<p>The tools and workflows developers rely on keep evolving, and several of these plugins never reached the level of adoption we hoped for. After reviewing usage trends, we’ve decided to move a set of low-usage plugins out of active development, so our team can focus on features with broader impact for Python developers.</p>



<p>A smaller set of bundled plugins also means a leaner, more maintainable codebase. As PyCharm continues to grow, we want to invest our engineering effort where it has the most impact and keep the IDE fast and responsive over time.</p>



<p>Unbundling and deprecating a plugin doesn’t necessarily mean deleting it. If a certain plugin’s functionality is still used, we’ll move that plugin’s code to a separate <a href="https://github.com/JetBrains/intellij-obsolete-plugins" target="_blank" rel="noopener">Obsolete Plugins repository</a>. The plugin will remain searchable and installable on JetBrains Marketplace with a fixed compatibility range, but will no longer be rebuilt with every new release or maintained by the PyCharm team.</p>



<h2 class="wp-block-heading">Which plugins are affected</h2>



<p>The following plugins are being deprecated; those currently bundled will be unbundled first:</p>



<ul class="wp-block-list">
<li>Data Wrangler</li>



<li>Hugging Face</li>



<li>Google Colab (Jupyter Notebook Colab)</li>



<li>Spark, including PySpark support</li>



<li>AI Playground</li>



<li>AI Agents Debugger</li>



<li>dbt</li>



<li>Databricks</li>
</ul>



<p>Other low-usage plugins may be deprecated in the same way in future releases.</p>



<h2 class="wp-block-heading">Timeline and what to expect</h2>



<p><strong>v2026.2</strong></p>



<ul class="wp-block-list">
<li>The bundled plugins listed above will be unbundled from PyCharm.</li>



<li>The PyCharm team will no longer develop new features for these plugins or maintain them.</li>



<li>Compatible versions will remain available for installation from JetBrains Marketplace and stay compatible with v2026.2.</li>



<li>The plugin source will be published in the Obsolete Plugins repository, where you can continue to build and install it manually.</li>
</ul>



<p><strong>v2026.3 and beyond</strong></p>



<ul class="wp-block-list">
<li>The PyCharm team will no longer publish compatible versions of these plugins starting from v2026.3.</li>
</ul>



<h2 class="wp-block-heading">What this means for you</h2>



<p>If you rely on any of these plugins, you can continue to install a compatible version from <a href="https://plugins.jetbrains.com/" target="_blank" rel="noopener">JetBrains Marketplace</a> for PyCharm 2026.2. Because the source moves to the <a href="https://github.com/JetBrains/intellij-obsolete-plugins" target="_blank" rel="noopener">Obsolete Plugins repository</a> under an open model, the community can keep building and installing the plugins manually. If you’re interested in maintaining one of them, we’d love to hear from you.</p>



<h2 class="wp-block-heading">Thank you</h2>



<p>We’re grateful to everyone who used these plugins, filed issues, and shared feedback over the years. Thank you!</p>



<p>The PyCharm team</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
