# On The Core API Names

You may be surprised seeing *attrs* classes being created using {func}`attrs.define` and with type annotated fields, instead of {func}`attr.s` and {func}`attr.ib()`.

Or, you wonder why the web and talks are full of this weird `attr.s` and `attr.ib` -- including people having strong opinions about it and using `attr.attrs` and `attr.attrib` instead.

And what even is `attr.dataclass` that's not documented but commonly used!?


## TL;DR

We recommend our modern APIs for new code:

% {func} syntax does currently not work for `.. function` definitions.

- {func}`attrs.define` to define a new class,
- [`attrs.mutable()`](attrs.mutable) is an alias for {func}`attrs.define`,
- [`attrs.frozen()`](attrs.frozen) is an alias for `define(frozen=True)`
- and {func}`attrs.field()` to define an attribute.

They have been added in *attrs* 20.1.0, they are expressive, and they have modern defaults like slots and type annotation awareness switched on by default.
Sometimes, they're referred to as *next-generation* or *NG* APIs.
As of *attrs* 21.3.0 you can also import them from the `attrs` package namespace.

The traditional, or *OG*, APIs {func}`attr.s` / {func}`attr.ib`, their serious-business aliases `attr.attrs` / `attr.attrib`, and the never-documented, but popular `attr.dataclass` easter egg will stay **forever**.

*attrs* will **never** force you to use type annotations.


## A Short History Lesson

At this point, *attrs* is an old project.
It had its first release in April 2015 -- back when most Python code was on Python 2.7 and Python 3.4 was the first Python 3 release that showed promise.
*attrs* was always Python 3-first, but [type annotations](https://peps.python.org/pep-0484/) came only into Python 3.5 that was released in September 2015 and were largely ignored until years later.

At this time, if you didn't want to implement all the {term}`dunder methods`, the most common way to create a class with some attributes on it was to subclass a {obj}`collections.namedtuple`, or one of the many hacks that allowed you to access dictionary keys using attribute lookup.

But *attrs* history goes even a bit further back, to the now-forgotten [*characteristic*](https://github.com/hynek/characteristic) that came out in May 2014 and already used a class decorator, but was overall too unergonomic.

In the wake of all of that, [Glyph](https://github.com/glyph) and [Hynek](https://github.com/hynek) came together on IRC and brainstormed how to take the good ideas of *characteristic*, but make them easier to use and read.
At this point the plan was not to make *attrs* what it is now -- a flexible class-building kit.
All we wanted was an ergonomic little library to succinctly define classes with attributes.

Under the impression of the unwieldy `characteristic` name, we went to the other side and decided to make the package name part of the API, and keep the API functions very short.
This led to the infamous {func}`attr.s` and {func}`attr.ib` which some found confusing and pronounced it as "attr dot s" or used a singular `@s` as the decorator.
But it was really just a way to say `attrs` and `attrib`[^attr].

[^attr]: We considered calling the PyPI package just `attr` too, but the name was already taken by an *ostensibly* inactive [package on PyPI](https://pypi.org/project/attr/#history).

Some people hated this cutey API from day one, which is why we added aliases for them that we called *serious business*: `@attr.attrs` and `attr.attrib()`.
Fans of them usually imported the names and didn't use the package name in the first place.
Unfortunately, the `attr` package name started creaking the moment we added `attr.Factory`, since it couldn’t be morphed into something meaningful in any way.
A problem that grew worse over time, as more APIs and even modules were added.

But overall, *attrs* in this shape was a **huge** success -- especially after Glyph's blog post [*The One Python Library Everyone Needs*](https://glyph.twistedmatrix.com/2016/08/attrs.html) in August 2016 and [*pytest*](https://docs.pytest.org/) adopting it.

Being able to just write:

```
@attr.s
class Point:
    x = attr.ib()
    y = attr.ib()
```

was a big step for those who wanted to write small, focused classes.

### Dataclasses Enter The Arena

A big change happened in May 2017 when Hynek sat down with [Guido van Rossum](https://en.wikipedia.org/wiki/Guido_van_Rossum) and [Eric V. Smith](https://github.com/ericvsmith) at PyCon US 2017.

Type annotations for class attributes have [just landed](https://peps.python.org/pep-0526/) in Python 3.6 and Guido felt like it would be a good mechanic to introduce something similar to *attrs* to the Python standard library.
The result, of course, was {pep}`557`[^stdlib] which eventually became the `dataclasses` module in Python 3.7.

[^stdlib]: The highly readable PEP also explains why *attrs* wasn't just added to the standard library.
    Don't believe the myths and rumors.

*attrs* at this point was lucky to have several people on board who were also very excited about type annotations and helped implement it; including a [Mypy plugin](https://medium.com/@Pilot-EPD-Blog/mypy-and-attrs-e1b0225e9ac6).
And so it happened that *attrs* [shipped](https://www.attrs.org/en/17.3.0.post2/changelog.html) the new method of defining classes more than half a year before Python 3.7 -- and thus `dataclasses` -- were released.

---

Due to backwards-compatibility concerns, this feature is off by default in the {func}`attr.s` decorator and has to be activated using `@attr.s(auto_attribs=True)`, though.
As a little easter egg and to save ourselves some typing, we've also [added](https://github.com/python-attrs/attrs/commit/88aa1c897dfe2ee4aa987e4a56f2ba1344a17238#diff-4fc63db1f2fcb7c6e464ee9a77c3c74e90dd191d1c9ffc3bdd1234d3a6663dc0R48) an alias called `attr.dataclass` that just set `auto_attribs=True`.
It was never documented, but people found it and used it and loved it.

Over the next months and years it became clear that type annotations have become the popular way to define classes and their attributes.
However, it has also become clear that some people viscerally hate type annotations.
We're determined to serve both.


### *attrs* TNG

Over its existence, *attrs* never stood still.
But since we also greatly care about backwards-compatibility and not breaking our users' code, many features and niceties have to be manually activated.

That is not only annoying, it also leads to the problem that many of *attrs*'s users don't even know what it can do for them.
We've spent years alone explaining that defining attributes using type annotations is in no way unique to {mod}`dataclasses`.

Finally we've decided to take the [Go route](https://go.dev/blog/module-compatibility):
Instead of fiddling with the old APIs -- whose names felt anachronistic anyway -- we'd define new ones, with better defaults.
So in July 2018, we [looked for better names](https://github.com/python-attrs/attrs/issues/408) and came up with {func}`attr.define`, {func}`attr.field`, and friends.
Then in January 2019, we [started looking for inconvenient defaults](https://github.com/python-attrs/attrs/issues/487) that we now could fix without any repercussions.

These APIs proved to be very popular, so we've finally changed the documentation to them in November of 2021.

All of this took way too long, of course.
One reason is the COVID-19 pandemic, but also our fear to fumble this historic chance to fix our APIs.

Finally, in December 2021, we've added the *attrs* package namespace.

We hope you like the result:

```
from attrs import define

@define
class Point:
    x: int
    y: int
```
