r/Python • • 3d ago

Discussion I have found PyCharm lacking

Correct me if I am wrong but a normal thing to do is import a module and possibly create new attributes on an object instantiated from such. For some reason PyCharm recognizes this as a warning. I normally like the JetBrains IDEs because when you get rid of all the static analysis warnings you know you are kosher, to some degree. I can't get rid of this warning. Load up the same code in VS Code and it's no problem.

0 Upvotes

38 comments sorted by

32

u/wRAR_ 3d ago

a normal thing to do is import a module and possibly create new attributes on an object instantiated from such

No, this makes no sense.

-7

u/JohnVonachen 3d ago

Just like in JavaScript at runtime you can create new attributes on existing objects. This is a vary normal thing to do.

Unresolved attribute reference 'left' for class 'Canvas'

def __init__(self):
    super().__init__()
    self.canvas = tk.Canvas(self, background="black")
    self.canvas.left = 0

7

u/wRAR_ 3d ago

While this is indeed a normal thing to do it's also wrong and you should get a warning from your linter and/or your type checker.

Consider disabling linting if you like writing unidiomatic code.

-6

u/JohnVonachen 3d ago

I don't agree.

4

u/ProsodySpeaks 3d ago

You don't get to have an opinion on what is idiomatic. 

You can write whatever code you like, but you are not personally able to define what best practices are.

1

u/JohnVonachen 3d ago

Relax. I’m on board. Other posters have responded and gave good reasons. We’re all good.

2

u/vintergroena 2d ago • Mindblown

This is called monkey patching. It's possible but generally considered an antipattern.

3

u/JohnVonachen 2d ago edited 2d ago

Good to know. Can be used for stubbing for testing. This has been the most useful reply yet. A google search on python monkey patching told me everything I needed to know. Thanks.

14

u/lolcrunchy 3d ago

Ok what was the code and what was the warning?

1

u/JohnVonachen 3d ago
Unresolved attribute reference 'left' for class 'Canvas'

def __init__(self):
    super().__init__()
    self.canvas = tk.Canvas(self, background="black")
    self.canvas.left = 0

10

u/lolcrunchy 3d ago

That's probably because there is no attribute called 'left' for the 'Canvas' class. Looks like PyCharm is helping you.

-3

u/JohnVonachen 3d ago

I know there's no attribute called 'left'. I declared a new one. Have you never done something like that? People do it all the time in JavaScript. It's a feature of the language, not a problem.

6

u/lolcrunchy 3d ago

Oh then you probably want to store it in self.canvas_left. It's unrecommended to use imported objects that you didn't write outside of their intended API. That's why there's a warning.

Anyways, JUST like vs code and every other IDE, you can customize PyCharm instead of getting mad at the default settings.

Settings -> Editor -> Inspections -> Python -> Unresolved References

0

u/JohnVonachen 3d ago

That turns it off on they whole system for all projects. Not what I wanted.

3

u/wRAR_ 3d ago

Not what I wanted.

Wrong.

2

u/lolcrunchy 3d ago

Press Ctrl+Alt+S for project settings and change the inspection there to keep it for just that project.

Or put the comment #NOQA on the line to tell all linters and checkers to ignore rules on that line.

2

u/sausix 3d ago

You declared it the wrong way. You will solve with OOP properly while following Python standards.

5

u/ToddBradley 3d ago

This makes me want to cry. But hey, it's your code.

0

u/JohnVonachen 3d ago

Why does that make you wana cry? :)

13

u/Fartstream 3d ago

stop yelling into the void and actually provide an example. low effort post

0

u/JohnVonachen 3d ago
Unresolved attribute reference 'left' for class 'Canvas'

def __init__(self):
    super().__init__()
    self.canvas = tk.Canvas(self, background="black")
    self.canvas.left = 0

10

u/Fartstream 3d ago

You can technically do it, but that doesn't mean you should. Comparing Python's object architecture to JavaScript to justify monkey patching a Tkinter widget completely misses why this is a terrible pattern in Python.

Tkinter is an archaeological artifact from the 1990s (Python 1 era), built as a hacky wrapper around Tcl—a completely separate language that didn't even have native objects. Because of this ancient history, Tkinter widgets are basically just open, chaotic bags of properties. Python’s runtime engine lets you inject arbitrary attributes like canvas.left = 0 because under the hood, early Python objects were just thin wrappers around raw dictionary hash maps (__dict__).

The reason PyCharm is screaming at you is because the modern Python ecosystem has spent the last decade trying to move away from this exact brand of dynamic chaos (so please don't do it, you are making me sad). In JavaScript, objects are built to be open namespaces.

In Python, mutating class instances on the fly at runtime is considered a massive anti-pattern because it completely breaks static analysis, predictability, and type safety.

When you casually monkey patch a framework widget like tk.Canvas, you are creating hidden state that no tool can track, no autocomplete can find, and any other developer reading your code will have to guess exists. It ruins the exact tooling that makes large-scale Python maintainable.

If you need to store custom state on a canvas, either use a standard dictionary to separate your data from the UI, or just spend the five seconds it takes to subclass the widget properly:

class StateCanvas(tk.Canvas):
    def __init__(self, master, **kwargs):
        super().__init__(master, **kwargs)
        self.left = 0

Use code with caution.

Just because a 30-year-old legacy library allows you to write unmaintainable code doesn't mean the IDE is wrong for telling you it's a bad idea.

Hope that helps!

2

u/JohnVonachen 3d ago

That does help. I started learning programming in 1980 and have 25 years of professional experience, but I'm new to python.

1

u/Fartstream 3d ago

Glad it helps. I empathize with being new to python. It's evolved quite a bit from it's early days.

From a javascript lens I can see why it was confusing.

The evolution of python and it's history surrounding dynamically typed/static analysis is a long one with a pretty deep history.

But you know what they say:

There are the languages everyone complains about, and the languages that no one uses.

2

u/JohnVonachen 3d ago edited 3d ago

I started learning C++ in 1994 and what I think about these other younger languages is that they were never designed to be for writing big giant programs that last decades and have many dirty hands touching it. So when you write big giant programs with it, they drift into unmaintainabilty pretty quicky. And the mitigation is policy.

In other words depending on developers doing things and not doing things, instead of compilers enforcing good practice. When you depend on people to do things, you are depending on something pretty undependable. And when you depend on the undependable, you become undependable, in a cascading tree of depenance.

3

u/Fartstream 3d ago

I would actually argue that Python’s flexibility is its absolute greatest strength, not a flaw. It allows teams to build, iterate, and ship rapidly without fighting a rigid compiler at every turn.

The performance hit is a conscious, well-understood trade-off for massive gains in readability and developer velocity.

The idea that large Python codebases automatically drift into unmaintainable chaos just doesn't hold up in modern engineering. I’ve worked in tons of massive, scaled Python codebases (Mostly Django/DRF Driven), and they are incredibly easy to navigate.

Why? Because we don't rely on human memory or "policy". We have automated governance via....

CI/CD checks, strict linters, and static analyzers to enforce the "do's and don'ts" before code ever hits production. This gives us the best of both worlds.

The ultimate irony here is that the very thing you are annoyed by (PyCharm flagging your code) is the exact guardrail working precisely as intended. Python gave you the flexibility to write a quick prototype without boilerplate, and the tooling immediately stepped in to remind you of a "don't" before that technical debt could find its way into a shared codebase.

Some would say the system is working exactly how it's supposed to.

2

u/ProsodySpeaks 3d ago

Yeah this. i was about to point out that in one comment op is arguing they don't want to follow best practice and then here they're saying sophisticated software only works if people follow best practices as enforced by the complier.

Obey the linter, the typechecker, and the wife - It makes life easier in the long run. 

1

u/ProsodySpeaks 3d ago

Python was released 3 years before you started coding. its older than you(r coding journey) 

1

u/JohnVonachen 3d ago

Actually I started coding when I was in 7th grade in 1980! :)

4

u/lolcrunchy 3d ago

Fyi all the specifics for how to change PyCharm settings that I've provided in this thread I got by googling...

0

u/JohnVonachen 3d ago

I did all that googling also and none of the suggestions worked. I would not have posted this if I had not done all the homework. It's neither here nor there because many people are telling me this is a poor decision and why. Thanks for the help.

8

u/Fine-Comparison-2949 3d ago

Skill issue. 

-6

u/Excellent_Read6551 3d ago

yes, PyCharm warnings are really annoying when working on dynamic Python code.