Hacker News new | ask | show | jobs
Python 3.7 released (python.org)
285 points by sply 2918 days ago
10 comments

Notable parts of this release (IMO):

* Data classes (https://docs.python.org/3.7/library/dataclasses.html)

* New breakpoint() builtin (https://docs.python.org/3.7/library/functions.html#breakpoin...)

* Dictionaries preserve insertion order. (Implemented in 3.6, but now is part of the official spec.)

Data classes are awesome! No more boilerplate __init__(self) methods needed.

Another notable part of this release is type annotations:

https://www.python.org/dev/peps/pep-0560/

I love python typing, and have been using it extensively in 3.6. Great to see it in the CPython core!

I've been looking forward to trying data classes, should be nice to avoid unnecessary code.

> The typing module is one of the heaviest and slowest modules in the standard library even with all the optimizations made.

Have you noticed any decreases in performance using core typing?

For those wondering, like I was, where that quote comes from, it's from PEP 560 "Core support for typing module and generic types" - https://www.python.org/dev/peps/pep-0560/
Not a python coder, but from my understanding they are essentially auto-constructors?
Technically, no, but that is how they are written. __init__ was always called after the instance was already created. I think it was originally useful for managing inheritance and baseclass initialization, which can be handled other less hard-coded ways now. I could be wrong.
> Dictionaries preserve insertion order. (Implemented in 3.6, but now is part of the official spec.)

That is a terrible decision. Call me a heretic.

Yes, I know it's a side effect of bringing in the bitmap index version from PyPy. Yes, I am aware that collections.OrderedDict is now an alias to internal dictionary type. And yes, I do understand that randomising the key traversal order could incur a performance penalty.

But a dictionary where keys come out in anything other than unspecified order is a subtle trap just waiting to blow up. I personally prefer golang's map behaviour - keys are always in unspecified order, and the order is different even between calls.

Personally I feel it is perfectly in line with one of Python’s core mentality, “We’re all grown-ups here.” The bahaviour is like Python lacking real access control: If you don’t think about it, it does not matter[#]; if you need it, it’s incredibly useful. You may not like it, and that’s fine, we agree to disagree.

[#]: Well, usually it doesn’t matter, and when it does, you have other ways to achieve similar results.

Can anyone explain why you'd want to use dataclasses over attrs in real code? Attrs does everything they do and more.

"Data Classes are intentionally less powerful than attrs. There is a long list of features that were sacrificed for the sake of simplicity and while the most obvious ones are validators, converters, and __slots__, it permeates throughout all APIs."

See: http://www.attrs.org/en/stable/why.html#data-classes

Because they’re in the standard library, and convenient. I would never use a third-party package just for some syntactic sugar.
I don't understand the inconvenience. Isn't it just adding `attrs` to requirements.txt once for the whole project, and then you get more features ever after?
Simple != easy. It is easy to add another dependency, but you've just added another piece to the puzzle that needs to be maintained.
That assumes you have a project. Some people write scripts in Python to use in the shell.
venvs work fine in the shell. See pipsi for automatic creation/management of the necessary venvs.
It's one more thing that can break in production.
Data classes look cool. Maybe replacing named tuples in my future code? They always felt awkward to work with.

Will data classes save a ton of memory since you’re specifying the types?

Data classes are just regular classes with some methods generated for you. For now you still have to specify __slots__ manually to save memory.
So what’s the point of specifying the types?
Over the last few years Python has gained a type annotation system. The primary goals are to improve testing, improve documentation (the type information is more likely to stay synchronized than docstring annotations), and improve user-feedback in environments like an IDE or Jupyter notebook.

These are called "type hints" because they are not enforced by the Python runtime.

Is the breakpoint builtin analogous to binding.pry in Ruby? If so...that is amazing!
Yes, it's quite similar. It's not THAT amazing though since it's just a convenience function over pdb.set_trace() which has been in the Python standard library for a very long time (2 decades or more).
Out of curiosity, I looked it up. According to a 'git annotate' of pdb.py, "def set_trace():" was added by Guido van Rossum on 1994-08-01 at 11:34:53 - almost 24 years ago.
Yeah, the main advantage seems to be that you can configure the debugger to use externally (I often "pip install ipdb" just to use IPython's shell instead of the default).
I have been looking to translate Moo/Mouse type stuff in Perl to a Python equivalent. I think Data Classes will definitely bring me closer to this.
Wow, I'm tempted to make the switch tomorrow but I literally just wrote tons of boilerplate today....
The new importlib.resources[0] module is a nice solution for accessing static data-files within a package/module. It replaces pkg_resources (or perhaps, standardizes/guarantees-presence) and is supposed to be more efficient.

There's also the new module-level "__getattr__(name):" function[1] which behaves as the class method does: catching undefined variable names and providing a way to easily, for example, generate objects dynamically, handle deprecated variables, and lazily load submodules. I have a feeling it's going to be (ab)used to do some really great meta-programming.

[0] https://docs.python.org/3.7/library/importlib.html#module-im... [1] https://www.python.org/dev/peps/pep-0562/

I've become a heavy user of attrs, a small library that makes it easy to replace named tuples with a class that automatically includes initialisation and string representation functions.

So I'm very glad to see data classes bringing this to the core language.

Why? attrs does it already.
I'm not a python dev, but isn't less dependencies generally better? Or is attrs in Python natively already?
Attrs isn't in python natively. Not sure why less dependencies would be better though.
Every dependency is one more thing that can go wrong in my mind. I always drop them at every opportunity.

There are some exceptions. Like I really don't want form building to be in the standard library, and I don't want to write it myself.

It is nice when your package manager only takes a short manage to fetch and build though, and you can have more confidence that any mistakes will be your own (under your control) rather than someone else's.

One less thing to worry about. Adds to build time etc.
Python does a lot of things that libraries can do. "Batteries included" and whatnot.
Data classes seem pretty neat. I haven't used attrs yet. And I rarely extend namedtuples, but it's nice to have a mechanism to do that built in.

breakpoint() is certainly more memorable than the current incantation.

Yes! I’ve never been able to convince anyone to use pdb.settrace. I think they see the pdb and assume there’s a whole new thing they’d have to learn.

If I tell them you just call breakpoint() they might be willing to try it out.

Nice to see deterministic pycs made it in. Hurrah for reproducibility.
Love data classes! Would've been even cooler if they could've been made immutable.

Oops, never mind: "It is not possible to create truly immutable Python objects. However, by passing frozen=True to the dataclass() decorator you can emulate immutability. In that case, dataclasses will add __setattr__() and __delattr__() methods to the class. These methods will raise a FrozenInstanceError when invoked."

Every time I read about the module-level __getattr__ I’m reminded of the infamous Wat talk and how the speaker says Ruby is awesome. Python is equally awesome, finally :p

https://www.destroyallsoftware.com/talks/wat

Hey, does anyone know where to find information about how python's releases are structured? For example, 3.6 exists and 3.7 is released. Without looking at the release details, should I be upgrading? Should I assume that it will break stuff, or assume that it won't, or should I make no assumptions? Etc...
3.6 to 3.7 is a minor release, only supposed to have new features, and not break existing code. Obviously, the probability of bugs is higher than in a micro release (e.g. 3.6.2 to 3.6.3), which only contains bugfixes. But I can't remember code from 2.6 breaking on 2.7, nor code from 3.5 breaking on 3.6.
Only point releases are support to avoid breaking code (though they sometime do).

Minor release may break code, though it should be rare. Python 3.7 reserves 'async' and 'await' as keywords so assignments like "async = 3", which worked in 3.6, will now fail.

Python has a deprecation warning system which can detect cases like this, but it must be enabled:

  % python -Wall
  Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 05:52:31)
  [GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
  Type "help", "copyright", "credits" or "license" for more information.
  >>> async = 3
  <stdin>:1: DeprecationWarning: 'async' and 'await' will become
  reserved keywords in Python 3.7
I personally never encounter that. However, there is a breaking stuff in this release: await and async are now keywords. This means that although they were part syntax we could make variable variables with these name until 3.6 but now it is not allowed.
I found the post on RealPython easier to digest for a quick glance of the new features:

https://realpython.com/python37-new-features

Does anyone know how long new versions of Python take to get into Homebrew? Will current Python 3.6 installations on Homebrew autoupdate to Python 3.7 when brew update/brew upgrade is run and the new version is packaged?
Usually, it should be within few days.

I don't see any pull requests yet.

3.5->3.6 python was updated in the same package, so I guess python 3.7 will replace python 3.6 too. You will get it after you run brew upgrade.

The PR is open here: https://github.com/Homebrew/homebrew-core/pull/29490

Looks like it's waiting for tests to pass at present.

i highly recommend pyenv.

`brew install pyenv; pyenv install 3.7`

You're welcome to create a PR. Homebrew's users are the primary contributors of package updates.
Did you mean pyenv? pipenv is a package manager. You can specify in pipenv which version of Python your project needs, but to utilize it requires that that the version is already installed on your system.
> to utilize it requires that that the version is already installed on your system.

Almost correct. It requires either that the version is already on your system, or it can find an installation of pyenv configured in the standard way (and, on some quirky situations with OSX, configured but pristine--without any pre-existing Python builds). In the latter case, it'll ask you if you want it to automatically build and cache/install a Python of the specified version.

And yes, the names all suck.