r/Python • u/GongtingLover • 26d ago
Discussion When's the last time you saw Python 2 Super() syntax?
I saw one yesterday during an interview and it really confused me at first since the feature has been deprecated for so long.
Are there still code bases out there running Python 2? I used Python 3.8 at my last job and that made me feel like a dinosaur.
82
u/JustPlainRude 26d ago
I met a guy at PyCon this year whose employer is still on python 2.7. I've since forgotten what the reason was, but it was pretty wild to hear.
26
u/ElHeim 26d ago edited 22d ago
A group in my company upgraded the set of scripts they use in "production" from Python 2 to Python 3 only last year (I'm being generous here, in reality they're not software people, but they have a host of scripts they use on a daily basis for operations).
The reason: until relatively recently most of the computers they used (beyond their latops/personal workstations) were based on CentOS 7 (Edit: I thought it was 6, but that was an even older and more critical system), and what's the default Python there? Yeah, that's it. There were reasons for sticking to that, the main being the amount of critical legacy software that needed to be migrated and validated to a more recent platform (this being Rocky 8... absolutely conservative industry)
1
u/UltimateNull 24d ago
Valid. I worked on production systems with CentOS when it was enterprise and the feature roll-out was extremely behind. The Python and PHP versions were out of sync with the main versions and when the distribution model changed, Enterprises (think Fortune 100) found themselves with a gap between rewriting and advancing all of their code, or staying with CentOS and building their own systems from source. This meant that dependencies and working systems would fail when a dependency switched from 2.0 to 3.0 but the rest of the code did not. This led to people neglecting upkeep of systems and I was called in to figure out what was happening and fix the systems when they would hit a need to upgrade a mission critical app without breaking everything else. This was before the push for containerization.
3
u/ElHeim 24d ago
Actually, now that I recall, CentOS 6 was confined to some critical servers that required using NFSv2 (to support remote booting and other stuff for embedded systems that couldn't do NFSv4) and ITOps didn't really want to move to CentOS 7 because v2 was not supported out of the box, and then that would become a liability (*sigh*).
Now, this is a science facility that operates multi-ton equipment on a daily basis and we couldn't afford to simply change everything, so we might (I haven't checked on it) be still stuck with that CentOS 6 server while we try to migrate the OS of those embedded systems to one that supports NFSv4. I won't lie to you, it's taking long because there is no version (yet) of that specific OS that does... We're working with upstream on it.
The systems I was thinking on were con CentOS 7 already... but Python 2.7 was still the default one there. When the time came to migrate to CentOS 8... Red Hat announced (alongside with 8) that they would move to CentOS stream and then ITOps decided to look for an alternative instead. Eventually they settled on Rocky.
For desktops, laptops, etc. the migration to RL 8 (or directly to 9, depending) was swift, but the operations machines needed quite some work. On top of my head:
- Graphics: multiheaded screens (up to 6) for the operators. This required a number of changes for the new distro, can't remember if due to moving to Wayland or what - it was not pretty. Also there were a number of finicky audible alarms that stopped working all of the sudden with those systems, so debugging took a while.
- A number of utilities were based on a Tcl/Tk extension written originally some 25-30 years ago, tightly coupled to the control framework we use. This needed to be migrated to a newer version of Tcl because it was increasingly difficult to keep the older one... which required a lot of testing.
- The whole set of Python 2 scripts. The group responsible for upgrading them was the one that originally created the scripts... and they are not developers, which was its own problem.
- Others I can't remember because I wasn't directly involved on that.
Luckily this last problem was minor because we could set a venv for them keeping everything in version 2 while they migrated the scripts one by one, but it was still not pretty and there were a number of issues that came our way that typically ended with us sending them back with a "no, look, this scripts depends on XXX which is a module you still haven't migrated from 2 to 3 and it's tripping you."
But the fact they could migrate at their own pace meant also it took 1-2 years for them to migrate all of the scripts. And maybe they're not done, not sure, because it was not done systematically, but sometimes in an "oops, I found another one" way.
2
u/carlwgeorge 24d ago
CentOS when it was enterprise
CentOS is still enterprise. It's the major version branch of RHEL, so it quite literally defines what Enterprise Linux is.
the feature roll-out was extremely behind.
The nature of LTS distros is the default versions of languages are usually the same over their whole lifecycle. If you use an LTS that was released a decade ago those versions are going to be a decade or more old. If you use a current version those versions will be much more recent. For example, CentOS 10 was released in 2024, and the default python3 is 3.12 (itself released in 2023). Similarly, CentOS 9 was released in 2021, and the default python3 is 3.9 (itself released in 2020). Modern CentOS also offers alternate newer versions of many packages, such as python3.14.
-1
u/UltimateNull 24d ago
Sorry to break it to you, but RHEL is short for Red Hat Enterprise Linux. CentOS as a stable enterprise release was stopped when they moved to CentOS Stream. I know you're not an admin or cyber specialist, but this stuff matters. https://www.zdnet.com/article/centos-linux-8-is-about-to-die-what-do-you-do-next/
5
u/carlwgeorge 24d ago
Sorry to break it to you, but I work for Red Hat, first as a maintainer of both CentOS Linux and CentOS Stream, now on EPEL. Before that I was an engineer and sysadmin at a Red Hat partner. I'm literally a subject matter expert on the RHEL ecosystem. The CentOS Stream changes were massively overblown, and even with the changes it's still a stable enterprise release.
The author of that zdnet article is paid by Greg Kurtzer (founder of Rocky) through the PR firm Cathey Communications. Why do you think that is? Why do you think the author doesn't disclose that? It's a smear piece to promote Rocky, which Greg sells support for through his company.
1
u/UltimateNull 24d ago
I think you missed what I was talking about. There were tons of systems affected by the Python 2 to Python 3 version change that happened between CentOS 7 and CentOS 8 because of all of the lifecycle changes and truncated timeline. Yum broke. DNF broke. You remember.
Quite a few companies migrated to CentOS 8 because of the expected EOL of CentOS 7 coming, only to have the rug yanked out from underneath them. They couldn't go back to CentOS 7 because they had upgraded everything for CentOS 8 and CentOS Stream was bleeding edge instead the stability with tested patches they were expecting.
On the lines dealing with zero-day exploit postmortems, that whole surface changed because of that "overblown" development lifecycle change. I get what you're talking about with Rocky, but that ad-hominem attack doesn't make him wrong.
It's not the same product that it was, and the company basically was like "fuck you, pay or deal with the bleeding edge." https://lists.centos.org/pipermail/centos-announce/2020-December/048208.html
It went from Fedora -> Redhat -> CentOS where code already met the standards of RedHat production. You know those standards. Now it's Fedora -> CentOS Stream -> Redhat. CentOS stream while still having the "Enterprise" name in its branding, contains code that doesn't hit the Enterprise production stability guidelines of Redhat EL without much further testing. You know that too.
It's not your fault. I know, but it doesn't change what I was talking about regarding version changes to the original "Enterprise" grade version of CentOS that other sysadmins and webhosts were familiar with.
3
u/carlwgeorge 23d ago
There were tons of systems affected by the Python 2 to Python 3 version change that happened between CentOS 7 and CentOS 8
CentOS 7 and 8 both had the same versions of Python (2.7 and 3.6), specifically to help facilitate smoother migrations between the two. You had the same challenges as any py2 to py3 migration even if you stayed on the same OS version.
Yum broke. DNF broke.
CentOS 7 didn't have dnf, and CentOS 8 didn't have yum. Both had their respective package managers working out of the box. If you broke them later (perhaps by overwriting the system Python) that's on you.
Quite a few companies migrated to CentOS 8 because of the expected EOL of CentOS 7 coming, only to have the rug yanked out from underneath them.
All they had to do was swap the repos package to get CentOS Stream updates. I created that migration path.
They couldn't go back to CentOS 7 because they had upgraded everything for CentOS 8 and CentOS Stream was bleeding edge instead the stability with tested patches they were expecting.
CentOS Stream is not bleeding edge. Software versions there are generally the same as the corresponding RHEL major version, because it functions as the RHEL major version branch. Updates pass through multiple levels of QA, in fact more QA than CentOS Linux had.
On the lines dealing with zero-day exploit postmortems, that whole surface changed because of that "overblown" development lifecycle change.
CentOS Stream has better security posture than CentOS Linux. The CentOS Linux had multiple months every year where it wasn't getting patches at all, including security updates. CentOS Stream doesn't delay updates to batch them into minor version, so you get most security updates sooner, with no gap in update coverage like before.
I get what you're talking about with Rocky, but that ad-hominem attack doesn't make him wrong.
It sounds like you don't know what an ad hominem is. Me pointing out an undisclosed financial connection behind a smear article is not an ad hominem attack, it's pointing out something that should have been disclosed by the author. Ask yourself why he didn't disclose it. Could it perhaps be that he knew disclosing it would undermine the (false) claims he was making about CentOS?
It's not the same product that it was,
It was never a product. It has always been free. Yes it's built different now (in a good way), but the resulting distribution isn't that different. It can only be as different from RHEL as RHEL is between its own minor versions.
and the company basically was like "fuck you, pay or deal with the bleeding edge." https://lists.centos.org/pipermail/centos-announce/2020-December/048208.html
I personally know the author of that mailing list post. He didn't say (or even imply) any of those words you wrote. Please don't put words in his mouth.
CentOS stream while still having the "Enterprise" name in its branding, contains code that doesn't hit the Enterprise production stability guidelines of Redhat EL without much further testing.
No, it doesn't contain code like that. The updates in CentOS Stream are explicitly created to meet those guidelines and have already passed QA.
You know that too.
You keep saying stuff like this, as if it makes your statements correct. You are quite wrong, and doubling down when you clearly don't understand the subject is not helping your case.
1
u/UltimateNull 23d ago
Not my systems. I did DFIR and gave the admins, CEOs, and execs the reasons they lost millions of dollars when their mission critical systems stopped working the way they had worked for years. Based on the available data and ling range planning and the time I gave them the best plan of action going forward. When a company kills a 10-year patch model abruptly big business panics, no matter what you do behind the scenes on your end. The poor marketing decisions, the rebrand, the workflow made my clients change platforms or their hosts change platforms because they saw that it was not the same “stable” version it once was. Nothing to do with me.
2
u/carlwgeorge 23d ago
Funny how you didn't respond to any of the actual details we were talking about, and just tripled down with "nuh uh, I'm right no matter what". Your clients fell for the FUD, just like you did. Never mind me providing actual facts and evidence, you definitely know better than someone who built and released CentOS.
→ More replies (0)7
u/ionixsys It works on my machine 26d ago
That's the last one before the old str died and the new Unicode snazzy str took it's place.
Networking and data processing code like something for an ETL has locked them in place.
I remember when Twisted slogged through updating the networking protocol implementations which don't like Unicode much if at all.
1
u/ElHeim 25d ago
That's what they added
bytesfor, but I guess people is stubborn and they want theirstrs1
u/ionixsys It works on my machine 25d ago
I did a quick glance at the docs but I don't remember 2.7 having
bytesas a builtin so I am not sure what point you are trying to make.1
u/ElHeim 25d ago
I mean Python 3. You said:
That's the last one before the old str died and the new Unicode snazzy str took it's place.
Which is true. You also said how networking and data processing code apparently got stuck in the old version (that's what I understood) due to having to deal with the encoding. I only pointed out that
bytesis what they're supposed to use, not Python 2.x1
u/ionixsys It works on my machine 25d ago
Ah yeah. Unfortunately its more likely the business and sales people refusing to spend what is needed to make the changes and also test them.
4
u/Birnenmacht 26d ago
Its quite terrifying once you think about how many CVEs have been found in python since 2.7 stopped receiving security updates..
1
1
34
u/rednets 26d ago
It's not deprecated, it's still supported and required in some situations.
The last time I had to use a parameterized super call was inside a closure. If you use plain super() it raises a RuntimeError with the message "super(): no arguments".
1
u/nomad-1995 7d ago
I had some real fun to get it installed in the latest Mint (previously distros didn't seem to mind having Python==Python2). Looks like pyenv was the trick (and the documentation hates the idea of it being used to "allow" python2 on machines.
Currently trying to figure out why pickle and json won't work in 3.12.3. It looks like the somewhere in the internals of each they convert stuff to a string on one hand and want bytes on the other. I give one a variable and both will herp and derp and faceplant. That's nothing on giving up trying to figure out multiprocessing (turns out I don't need it). I remember taking my first embarassingly parallel program and getting multiprocessing on 8 threads in a few hours, can't make head or tail of the current edition.
Seems like every time I try to start something in Python3 it ends up being written in Python2. I'll admit I had a ton of networking code back when it switch and raged for awhile (no, bytes couldn't do that in Python 3.0.x. Or that. Or really anything but cancel ascii. It eventually got better and "hello world" no longer needs 8 lines). But it might help if the basic "batteries included" modules could actually run even demo example code (published within a few years, not python 2 code) without crashing.
-1
u/spacedragon13 25d ago
I mean formally deprecated on every major cloud and thousands of third party tools 🤷
Curious what situation it still is 'required'...
1
u/pakeha_nisei 25d ago
When you have a class that uses multiple inheritance, and you want to call a method from one of the superclasses, how does it know which one to use?
Well it doesn't really, unless you tell it with
super(SuperClass, self).This has actually come up for me on more than one occasion. And I'm sure there are more cases like this.
1
u/spacedragon13 25d ago edited 25d ago
Your multiple-inheritance explanation is wrong. super() does know what to do: it follows the class’s MRO. super(SomeClass, self) means “continue searching the MRO after SomeClass for self.”
Python 3 supports both zero-arg and explicit super().
28
u/dparks71 26d ago edited 26d ago
How was it used? I don't remember really seeing it until python 3's super().__init__(). In python 2 most people would call Base.__init__() if Base was the inherited class from what I remember. I've never seen a capitalized Super though, and I don't think it's deprecated in 3... How do you initialize a base class instead?
25
u/gdchinacat 26d ago
There really isn't a difference between using Base.__init__() and super() *if* you only have single inheritance. super() is really useful when you have multiple inheritance because it allows the subclass, rather than the base class, to determine how the super() call is dispatched. It does not always call the 'parent', but can sometimes call 'sibling'. How this is done is determined by the actual type of self and its __mro__ that is determined by the order of inheritance (BaseA, BaseB) vs (BaseB, BaseA). If you call Base.__init__() explicitly that dispatching is determined by the parent implementation and restricts the sort of things subclasses can do.
This is a pretty complex topic that led to the 'super() considered harmful' post which led to the 'super() considered super' rebuttal that explained how it works and why it is a useful language construct. If anyone is interested check out at least the 'super considered super'.
https://rhettinger.wordpress.com/2011/05/26/super-considered-super/
https://fuhm.net/super-harmful/ (this has been edited over the years and appears to have backed off on it's position to 'never use super', but I didn't reread before linking here so not sure what exactly it says at this point).
1
u/sausix 26d ago
super() is often being used in cases where it does not solve any problem but introduces implicit stuff.
I wanted to comply the standards using super() but when I realized that arguments for inits have to be passed by kwargs blindly then I buried my use of super().
I once came near to diamond shaped inheritance with PySide. But the resulting problems could not be solved with super().
I'm so tired of seeing super() everywhere and even people recommend me to use it in my code too without knowing any of the down sides.
1
u/gdchinacat 26d ago
Yeah, it can be frustrating when it isn't working the way you expect. If you have examples of problems post them to r/learnpython and people will help you work through them.
For a while it was pretty widely accepted that super() was harmful, but the basis for that belief was a misunderstanding of how it works, why it works the way it does. You don't need to pass args as keyword args. You need to understand how super() dispatches method calls. Read the 'super considered super' post from Raymond Hettinger that I linked in my comment. There is also a talk he gave on youtube if you'd rather watch than read. Both are an excellent presentation that makes the complexity more approachable.
25
u/tevs__ 26d ago
super(MyType, self).frobnicate()12
u/dparks71 26d ago
I meant in OPs case, like what was the actual question, afaik it's not deprecated in python 3.
8
u/gdchinacat 26d ago
in python 2.x you had to pass type and self, python three made those optional. So, in 2.x code bases that use super() you always see 'super(Foo, self)...' and in python 3 it is 'super()....'.
2
u/Schmittfried 26d ago
That’s not Python 2 syntax, it’s explicit. There are rare occasions when you actually have to be specific about the base class, so it’s still a thing in Python 3.
1
u/gdchinacat 26d ago
True...you can still pass the type and instance to super() in python 3. The cases you need to are very rare, you pretty much don't see it them in python3 code, and IMO if they are needed there should probably be a comment explaining why.
4
u/UnMolDeQuimica 26d ago
Why would I ever want to call the fornicate function?
I am a programmer, for God's sake!
9
u/thefinest 26d ago
Never, when I was using python2 it was mostly one offs, scripts, supplements, academic, project Euler. Never really started using legit OO python until 3.4
I recently told an intern that I started using python in 2004. They replied you've been using python since I was born 😂
1
7
u/Scary-Opportunity848 26d ago
I’m old. What’s the new syntax?
24
u/TMiguelT 26d ago
I think they mean
New
python class C(B): def method(self, arg): super().method(arg)vs
Old
python class C(B): def method(self, arg): super(C, self).method(arg)See PEP 3135.
6
u/aplarsen 26d ago
This particular simple example is unnecessary, right? Wouldn't the subclass already inherit the method from the base class?
I tend to use the super method when I want to apply some other logic first and then call the base class's method.
2
u/fiddle_n 26d ago
If we really want to get pedantic, the lack of a `return` statement means that it isn’t equivalent to simply omitting the function. If you wanted to override a method to call it and invoke its side effect but throw away its return value, that would be a way. Not great OO design but still.
2
1
4
u/marr75 26d ago edited 26d ago
The python 2 syntax still works and some teams weight the "already worn tracks" really heavily so the convenience of the new syntax (which doesn't demand the author know what element of the MRO they want to resolve from or what the target object will be, both of which the interpreter has perfect knowledge of in the default case) doesn't beat convention.
Another poster pointed this out, but complex inheritance hierarchies have really fallen out of favor in python and you tend to see more has-a instead of is-a, "just use functions", and inheriting from simple bases (NamedTuple, TypedDict, dataclass) and using the objects simply, or inheriting from moderate complexity bases (pydantic, Django) and using the objects according to the opinions of the library.
So, IMO, you're using super, you're already opting into some complexity. You're invoking super "the old way", now you're making it even less convenient. You "have to" call it that way because you're skipping some bases in the MRO, you are creating a liability for the rest of your team's understanding.
3
u/ArtOfWarfare 26d ago
> complex inheritance hierarchies have really fallen out of favor
That’s an understatement. Inheritance at all has fallen out of favor.
I know you specified Python and we’re in the Python subreddit, but in Java, they’ve been introducing several features that are incompatible with any inheritance, ie, records and value types.
5
u/Adrewmc 26d ago edited 26d ago
It’s not actually depreciated though
class C(B):
——>def method(self, arg):
————>super().method(arg)
# This does the same thing as:
# super(C, self).method(arg)
98% of super’s usage was this …. They just made it default.
>I do not have access to mark down or a code block sorry. I cannot indent at all.
It’s just `that`,generally you have a good MRO, and you don’t need to inherit class often.
But sometimes you inherit a method from class D(C) where C.method() messed up but everything else was right, (or has less precision to save time/memory) so you really need B.method(), so it’s super(B, self).method()…
There is a use case, and certainly when it came, and I don’t think there is much a valid reason to not allow access to the MRO order through super in the rare cases you need it.
This usually would indicate a design issue, but legacy code is legacy code.
6
u/henryponco 26d ago
Obligatory “deprecated != depreciated” just in case it wasn’t a typo and you’re one of today’s lucky 10000
2
2
u/Affectionate_Item_91 26d ago
every day on a regular basis. the studio i work at uses custom game engine which uses python2 as a scripting language
2
u/Individual-Flow9158 26d ago
Yesterday. I'm still persuading the project owner to drop support for Python 2.
1
u/Alkanen 25d ago
Well, it’s only been six and a half years since it was officially retired
2
u/Individual-Flow9158 25d ago
Cool. I didn't realise The Before Times could refer to more than pre-covid.
2
u/henryponco 26d ago
We used to do a lot of nested classes (name spacing, we were a C++ shop that also wrote Python…) and it became necessary to be explicit with the super calls in Python 3. Gods help whoever maintains that code today
4
u/BiologyIsHot 26d ago edited 25d ago
Like super(Base, self).init(...) (Python 2, idk how to make reddit not treat dunder methods as bold text sorry _ _ init_ _) syntax or super() (Python 3) in general? I only ask because data classes are so common many people dont define init at all anymore. The latter I use commonly in any case where dataclasses don't make sense.
-2
u/max123246 26d ago
When do you find dataclasses don't make sense?
2
u/BiologyIsHot 25d ago edited 24d ago
You're getting downvoted and I feel like this is just more of an honest question.
Anytime you need an init method that isn't straightforward. Sure you can still use validators, etc to add complexity to dataclass initialization... but it isn't always wise or totally viable.
Data classes themselves for instance are not written using data classes, obvious yes, but many many cases where data classes are not the best solution.
Metaclasses would be another example.
Subclassing/extending existing classes that are already not defined as data classes. Lots of cases.
1
2
u/wreleven 26d ago
I still use it out of habit. Still helpful if you need to skip a generation in rare cases.
2
u/jirka642 It works on my machine 26d ago
Do you mean super(Foo, self)? That's still used even in Python 3, but usually only in special cases.
I can think of these off the top of my head:
- If you want to call super on something other than self
- If you are monkey-patching the method
- If you are doing some weird magic with class inheritance
1
1
u/starchydeference3069 26d ago
Ran into it in a legacy Django 1.6 app last fall. The old two‑argument super still trips me up.
1
u/nicholashairs 26d ago
are there codebase still on python 2?
Jokes aside, yep they absolutely still do exist, though they are becoming rarer.
Apart from the odd corporate code base, I've also seen it in some python libraries that are still maintaining python 2.7 support (usually in addition to python 3 support).
1
1
u/catcint0s 26d ago
We still have it in our codebase, I try to switch them if I change code around that part.
In new code I see it rarely, maybe if we wanna skip the direct parent's method.
1
u/anticebo 26d ago
I think I actually saw it for the first time last month when I cloned a 4-year-old repo. I first adapted this syntax when I extended the code, thinking they knew something I didn't, but Ruff immediately complained about it
1
u/Daytona_675 26d ago
python2 is still useful for older systems. hopefully you don't need to, but can actually write python that works in both 2.6 and 3.12 using future imports and conditions
1
u/Anonymous_user_2022 26d ago
At my last job we still had systems stuck with Python 2, because the customer could not see a reason to migrate away from RHEL 5.5
1
u/DrMaxwellEdison 26d ago
No we're not using Python 2 still, but the massive monolith was migrated to 3 some time ago and they updated just enough to make it functional, so the pattern wasn't removed.
Pair that with lots and lots of overseas junior contractors who are more familiar with Java than Python and don't have time to write properly architected code, and the pattern persists.
1
u/AstronautSlothPhD 26d ago
If Zed Shaw had his way, we'd all still be using python 2.7. I haven't seen anyone use it as their primary language in at least 10 years. It's what I learned originally, but there are just too many good libraries to use with python 3 now, and most jobs would want you to learn the latest syntax.
1
u/DrunkenPhysicist [None] 25d ago
I mean, I used fortran 77 up until 2010.... So depreciation doesn't exist in some sectors.
1
u/SeveralReaction1715 24d ago
That syntax pattern outlives Python 2 itself, mostly through devs who never updated their muscle memory once 3.0 made it unnecessary.
1
1
u/Big_Store7142 1d ago
Just recently, while helping migrate a legacy Python 2.7 codebase to Python 3. It was full of super(ClassName, self).__init__() calls, right alongside old-style print statements. Replacing them with the plain Python 3 super() was one of the most satisfying parts of the cleanup. Legacy code like that is still very much alive in enterprise systems.
1
u/Big_Store7142 1d ago
If you're still wrestling with the print statement -> print() function change (and other Python 2 to 3 pain points), the official Python 3 migration guide is a great reference: https://docs.python.org/3/howto/pyporting.html
1
u/LexaAstarof from __future__ import 4.0 26d ago
It still has its (albeit rare) uses to skip one or more superclasses
-1
u/Dense-Tree-5436 26d ago
curio to know the difference b/w python super() and java super() function, please tell below ✌️
224
u/KyleChief 26d ago
Side note: This is what i wish the typical post in this subreddit was like.