Commit Graph

67 Commits

Author SHA1 Message Date
Hynek Schlawack 2f1014aa60
Black dropped us 5 years ago
31f4105731
2024-09-05 09:02:00 +02:00
Hynek Schlawack 6e51cb7c40
Remove missed hashes in tests 2024-08-03 15:41:27 +02:00
Hynek Schlawack bde3f58cfe
Deprecate hash for unsafe_hash (#1323)
* Deprecate hash for unsafe_hash

It's the standard -- what are we gonna do.

* Add deprecation tests

* Add news fragment
2024-08-03 15:19:21 +02:00
Hynek Schlawack 1967be0eb6
Move factory tests where they belong 2024-03-17 09:15:36 +01:00
Hynek Schlawack 4b1d869e9a
Simplify slot field detection 2024-03-17 07:27:41 +01:00
Hynek Schlawack 75d54c2197
Black 24 2024-01-26 08:15:53 +01:00
Victor Song c2824ac30f
Pass args from `__init__` to `__attrs_pre_init__` if requested (#1187)
* Pass args from `__init__` to `__attrs_pre_init__` if requested

Detect if `__attrs_pre_init__` has arguments besides `self`
using `inspect.signature`. If so, pass `__attrs_pre_init__`
the same arguments that `__init__` (or `__attrs_init__`)
expects.

* Add changelog entry for `__attrs_pre_init__` args changes

* Don't use monkeypatch in new code

* Clarify docs

* Missed one monkeypatching

---------

Co-authored-by: Hynek Schlawack <hs@ox.cx>
2023-09-29 08:47:51 +02:00
Hynek Schlawack a5cbd51fd9
Tighten linting (#1175)
* Tighten linting

* Consistency

* Simplify config

* Simplify
2023-08-20 12:03:53 +02:00
Kevin M Granger c860e9dd25
Use enum for typing NOTHING (#983)
* Use enum for typing NOTHING.

This will allow those extending attrs
to type NOTHING as Literal[NOTHING].

* Make test_dunders test `NOTHING` directly

* Reflect NOTHING enum typing in __init__.pyi

* Fix docs for NOTHING

* Add changelog entry

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: Hynek Schlawack <hs@ox.cx>
Co-authored-by: Tin Tvrtković <tinchester@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-27 17:41:56 +02:00
Hynek Schlawack 3843452516
Replace omnipresent pytest.mark.parametrize("(slots|frozen)" w/ fixture (#1002)
Replace omnipresent pytest.mark.parametrize("(slots|frozen)", [True, False]) w/ fixture
2022-08-11 09:35:39 +02:00
Hynek Schlawack 980c8b04f5
Drop Python 2.7 (#936)
* Drop Python 2.7

The tooling situation around Python 2 has deteriorate to such a degree that
upholding compatibility is not tenable anymore for a volunteer-run project.

Signed-off-by: Hynek Schlawack <hs@ox.cx>

* Add newsfragment

* Run Python 3.5 under coverage to make up for Python 2.7

* Wait for py35 in parallel

* Remove fullmatch kludge

* Remove Python 2-specific code

* Revert empty slot test

Also disable pyupgrade on that file.

Signed-off-by: Hynek Schlawack <hs@ox.cx>

* We DO run under 3.5

* Remove __qualname__ workarounds

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update changelog.d/936.breaking.rst

Co-authored-by: Tin Tvrtković <tinchester@gmail.com>

* Compare methods using is

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Tin Tvrtković <tinchester@gmail.com>
2022-03-21 08:47:47 +01:00
Hynek Schlawack 046beaaaaa Apply SPDX IDs 2021-12-27 09:29:09 +01:00
paul fisher 554d6f293d
Pull thread-local into _compat module to fix cloudpickling. (#857)
Because cloudpickle tries to pickle a function's globals, when it
pickled an attrs instance, it would try to pickle the `__repr__` method
and its globals, which included a `threading.local`. This broke
cloudpickle for all attrs classes unless they explicitly specified
`repr=False`. Modules, however, are pickled by reference, not by value,
so moving the repr into a different module means we can put `_compat`
into the function's globals and not worry about direct references.
Includes a test to ensure that attrs and cloudpickle remain compatible.

Also adds an explanation of the reason we even *have* that global
thread-local variable.  It wasn't completely obvious to a reader why
the thread-local was needed to track reference cycles in `__repr__`
calls, and the test did not previously contain a cycle that touched
a non-attrs value. This change adds a comment explaining the need
and tests a cycle that contains non-attrs values.

Fixes:
- https://github.com/python-attrs/attrs/issues/458
- https://github.com/cloudpipe/cloudpickle/issues/320
2021-11-04 06:52:10 +01:00
Tin Tvrtković 38580632ce
Rework linecache handling (#828)
* Rework linecache handling

* lint

* Add changelog
2021-06-30 08:28:56 +02:00
Hynek Schlawack 20c2d4fc0c
Optimize the case of on_setattr=validate & no validators (#817)
* Optimize the case of on_setattr=validate & no validators

This is important because define/mutable have on_setattr=setters.validate on
default.

Fixes #816

Signed-off-by: Hynek Schlawack <hs@ox.cx>

* Grammar
2021-05-17 09:24:46 +02:00
Hynek Schlawack 03d3fc7a71
Add Python 3.10 support (#763)
* Add Python 3.10 support

Python 3.10 has string types everywhere and that has unmasked a bunch of
bugs/edge cases in our code.

Especially the hooks code need a resolving helper for string types. I'm leaving
that for a separate PR.

Fixes #716

* More robust quote handling

* Use resolve_types decorator where possible

* Use a helper for __init__ annotations

* Add test for various ClassVars
2021-02-22 12:56:44 +01:00
Antonio Botelho aefdb117fa
Allow user to customize how an attribute is compared (#435) (#627)
* Updated implementation of comparison behaviour customization.

* Fixed version of next release, updates newsfragment and documentation.

* Fixed documentation.

* Fixed documentation.

* Fixed comments and changelog.

* Fix doctest error

* Update src/attr/_make.py

Co-authored-by: Hynek Schlawack <hs@ox.cx>

* Pass eq_key and order_key explicitly in _CountingAttr

* Merged with master and resolved conflics after introduction of _make_method

Co-authored-by: Antonio Botelho <antonio@inhames.com>
Co-authored-by: Hynek Schlawack <hs@ox.cx>
2021-02-22 08:48:34 +01:00
Venky Iyer efcbae51cd
__attrs_pre_init__ (#750)
* add pre-init following post-init pattern

* add tests

* add changelog

* some typos
2021-01-25 07:31:37 +01:00
Venky Iyer 654aa92475
__attrs_init__() (#731) 2021-01-23 13:03:04 +01:00
Hynek Schlawack f132c07e55
Make NOTHING falsey (#732)
* Make NOTHING falsey

Fixes #720

* Add newsfragment

* Python 2
2020-12-21 06:39:58 +01:00
Hynek Schlawack f680c5b83e pre-commit autoupdate
Latest black required to remove a bunch of commas to prevent line explosion.
2020-09-01 09:56:52 +02:00
Hynek Schlawack 2f6fd8516c
Add on_setattr hooks to attr.s and attr.ib (#660)
* Add on_setattr hooks to attr.s and attr.ib

Signed-off-by: Hynek Schlawack <hs@ox.cx>

* Add PR newsfragment

* Fix attr.s doc sig

* Make _DisableType private

* Mark setters.frozen as NoReturn

* Rename setters.DISABLE to setters.NO_OP to clarify its purpose

DISABLE sounds less purposeful and doesn't convey its meaning as well.

* Fix type

* Loosen up type for convert even further

* Tighten type a tiny bit
2020-07-20 12:43:10 +02:00
Paul Ganssle d6a65fb89f
Use a wrapper class for cache hash to prevent cache serialization (#620)
* Use an self-clearing subclass to store hash cache

Rather than attempting to remove the hash cache from the object state on
deserialization or serialization, instead we store the hash cache in an
object that reduces to None, thus clearing itself when pickled or
copied.

This fixes GH #494 and #613.

Co-authored-by: Matt Wozniski <godlygeek@gmail.com>

* Add test for two-argument __reduce__

I couldn't think of any way to make a useful and meaningful class that
has no state and also has no custom __reduce__ method, so I went
minimalist with it.

* Improve test for hash clearing behavior.

Previously, there was some miniscule risk of hash collision, and also it
was relying on the implementation details of `pickle` (the assumption
that `hash()` is never called as part of `pickle.loads`).

* Add improved testing around cache_hash

* Update src/attr/_make.py

Co-Authored-By: Ryan Gabbard <gabbard@isi.edu>

* Update comment in slots_setstate

Since the cached hash value is not actually serialized in __getstate__,
__setstate__ is not actually "clearing" it on deserialization - it's
initializing the value to None.

* Add changelog entry

* Remove changelog for #611

This change was overshadowed by a more fundamental change in #620.

Co-authored-by: Matt Wozniski <godlygeek@gmail.com>
Co-authored-by: Ryan Gabbard <gabbard@isi.edu>
2020-02-10 17:16:07 +01:00
Hynek Schlawack 08fcfe91d4
Split cmp into eq and order (#574)
* Split cmp into eq and order

Fixes #170

* Fix tests on old pypy3 versions

Old as in: currently on AP.

* Fix issue number and clarify newsfragment

* Clarify behavior and interaction between cmp/eq/order

* This sounds better

* Address Julian's review comments

* Missed a cmp

* Test the behavior of Attribute.cmp

* Make test more idiomatic

* Explain assumptions

* Clarify comment

* Grammar

* One more cmp!
2019-09-22 15:07:19 +02:00
wouter bolsterlee 0b913645c5 support custom repr() callable for attributes (#568)
* wip: support custom repr() callable for attributes

see #567

* extend ‘repr=...’ arg type in .pyi stubs

* expand docstring for attr.ib()

* add changelog entry

* add docs with example

* improve my copy/paste skills 🙈

* fix grammar

* fix typo in changelog entry

* fix and improve attrib() docstring

* detect custom repr() once, not per call. be strict about bool.

* use rst syntax, not markdown

* apply hynek's suggestions for changelog entry

* add ‘versionchanged’ note in docstring

* add custom attribute repr= to typing example

* simplify comment
2019-09-06 14:26:08 +02:00
David Euresti eda9f2de6f Make unique_filename not depend on repr. (#560)
* Make unique_filename not depend on repr.

For debugging purposes, when a method is created it needs to be put
into a "filename".  This filename was generated using `repr(attrs)`
however this meant that the filename could change every time the
program was loaded depending on the whims of repr.  (In particular
free functions and lambdas would include ids)

This solves the problem by changing the name to be <attrs generated
{method} {module}.{qualname}> If it should happen that the name is
taken then -2 will be appended and incremented until a free filename
is found.

* Add tests

* Fix tests and changelog
2019-08-01 12:42:13 +02:00
Hynek Schlawack 4b88f924d6 Remove _add_init
More concretely: move it to tests. It was dead code for a while however its
unittests are still valuable as the exercise quite a bit of _make_init.
2019-02-27 07:24:24 +01:00
Hynek Schlawack 1fada3d374 Be consistent in calling slotted classes slotted 2019-02-25 16:09:57 +01:00
Hynek Schlawack 3421b4bd97 Split test and fix warning
message is deprecated.
2019-02-02 14:36:56 +01:00
Ryan Gabbard d2be76c964 Clear cache hash on de-serialization (#489)
* Don't cache hash codes across deserialization.

 Because the hash code cache field gets serialized and deserialized by
 Pickle, previously when you deserialize a cache_hash=True attrs object, the
 hashcode will be the hashcode the object had at serialization-time.
 However, if your object had fields with hash codes which were not
 deterministic between interpreter runs, then on a new interpreter run
 your deserialized object would have a hash code which differs from a
 newly created identical object.

 This commit fixes that by clearing the cache on deserialization. It
 needs to override the __setstate__ method to do so, so this commit
 also forbids using a custom __setstate__ on a cache_hash=True object.

Closes #482 .

* Improve exception type

* Minor tweaks to comments formatting

* Fix test for Python 2.7

* Fix error in comment

* Make nomenclature consistent for slotted/dict classes

* Remove hasattr()

* Improve comments and error message for custom __setstate__ + cache_hash=True

* Drop use of  for test classes for cache hash serialization

* Make changelog note this is a breaking change

* Make exception message point to tracking issue

* Fix test classes for Python 2.7
2019-02-02 14:32:01 +01:00
Ryan Gabbard 3e0ecbd891 Cache hash codes (#426)
* First stab at implementing hashcode caching (#423)

Currently all existing tests pass but no cache_hash tests have yet
been added.

* Existing hash tests now pass on cache_hash classes

* Add towncrier change log

* Add documentation for cache_hash

* Fixes bug with check that init=True if cache_hash=True

* Fix long lines

* Fix documentation issues

* Add test for cache_hash requiring init

* Improve test coverage

* Remove now unnecessary 'pass'

* Add periods to the end of exception strings

* Add test docstrings for cache_hash tests

* Clarify documentation of cache_hash

* Recommend that hashable classes be frozen

* Fix test references for exception messages
2018-08-20 06:46:52 +02:00
Hynek Schlawack a372d51b7b
Fade to Black (#392) 2018-06-10 19:40:07 +02:00
Glyph 5e46afda49
return "..." rather than raising RecursionError for repr() on a cyclic object
Fixes #95
2018-03-17 01:32:28 -07:00
Yann Kaiser 9d441d70ab Fix __repr__ crashing when a member is uninitialized or deleted (#308) 2017-12-06 10:21:58 -08:00
Hynek Schlawack ef9a062022
Use isort so we can stop thinking about imports (#297) 2017-11-26 22:18:07 +01:00
Hynek Schlawack 03c10ad0ef Use new serious biz names in internal code (#257)
* Use new serious biz names

* Use offical API in tests where possible

* Fix flake8
2017-10-02 19:32:10 +02:00
Hynek Schlawack 8b490b8586 Stop setting attributes on class bodies (#253)
* Stop setting attributes on class bodies

This behavior has been deprecated since 16.1 and can now be removed in
accordance with our backward-compatibility policy.

* We don't need iterkeys anymore
2017-10-02 12:14:37 +02:00
Andy Freeland a6cf2d5637 Fix unbound __str__ on Python 2 when slots=True (#199)
Previously:

```pycon
>>> import attr
>>> @attr.s(str=True, slots=True)
... class A(object):
...     a = attr.ib()
...
>>> a = A(1)
>>> str(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method repr_() must be called with A instance as first argument (got nothing instead)
```

Fixes #198.
2017-06-01 09:30:31 +02:00
Hynek Schlawack f560500886 Fix hashing behavior (#142) 2017-02-19 09:51:43 +01:00
Hynek Schlawack b0942e1b2e Add str argument to @attr.s
Fixes #112
2016-11-20 15:52:11 +01:00
Tin Tvrtković 0fac9215b8 Introduce attribute metadata. (#96) 2016-11-19 09:47:03 +01:00
Hynek Schlawack cfa6d2e99f Implement immutability (#60) 2016-08-20 18:45:15 +02:00
Hynek Schlawack b337f5b9d5 Move test helpers into an utils module
__init__.py should never contain any code.
2016-08-15 15:27:13 +02:00
Hynek Schlawack 4b94e0314c Fix _Nothing class' __eq__
All instances used to be equal to anything.  Didn't pop up because attrs
always compares them using `is`.
2016-04-28 10:32:38 +02:00
Tin Tvrtkovic 821e8537af We hypothesizin'. 2016-03-23 00:15:14 +01:00
Tin Tvrtkovic 37bc4b878c Rename class_ to cls.
Fix docstrings.
Fix missing parens in a test.
2016-03-17 19:40:11 +01:00
Tin Tvrtkovic 7b201eb199 Initial slots implementation. 2016-03-14 03:02:13 +01:00
Hynek Schlawack 174d37f941 Allow mandatory attributes after init=False attrs
Maybe not the best design but a valid case nonetheless.
2016-02-06 12:20:37 +01:00
Hynek Schlawack 1af3eaa877 Allow the case of initializing attributes that are set to `init=False`
This allows for clean initializer parameter lists while being able to
initialize attributes to default values.
2015-12-19 13:43:07 +01:00
Hynek Schlawack 788ade3bcf Fix flake8 2015-07-03 12:15:05 +02:00