* Don't reset custom __setattr__ in slotted classes
Fixes#680
Signed-off-by: Hynek Schlawack <hs@ox.cx>
* Simplify
Signed-off-by: Hynek Schlawack <hs@ox.cx>
* Be defensive about __bases__
Signed-off-by: Hynek Schlawack <hs@ox.cx>
* _Classes_ always have a __dict__
* Tighten xfail
* Clarify what need to be reset and when
Signed-off-by: Hynek Schlawack <hs@ox.cx>
* Reset __attrs_own_setattr__ along with __setattr__
Signed-off-by: Hynek Schlawack <hs@ox.cx>
* Update src/attr/_make.py
Co-authored-by: Paul Ganssle <paul@ganssle.io>
* Differentiate between own (= attrs) and custom (= user) __setattrs__
Signed-off-by: Hynek Schlawack <hs@ox.cx>
* We've always used __bases__ in our call to type()
So no reason for being defensive.
* Update tests/test_setattr.py
Co-authored-by: Paul Ganssle <paul@ganssle.io>
Co-authored-by: Paul Ganssle <paul@ganssle.io>
* Add attr.auto/mutable/frozen
Prepare for import attrs y'all!
Signed-off-by: Hynek Schlawack <hs@ox.cx>
* Try combining coverage using 3.8, always
* Add tests for overriding of auto_attribs
* Clarifications
* Add newsfragment
* s/auto/define
This is going be the next-gen name anyways, so no need to introduce new names.
Signed-off-by: Hynek Schlawack <hs@ox.cx>
* Missed two
* Add type stubs
* Beg for patience
* Explain second setup-python action
* fix comment
* Add attr.resolve_types
This adds `attr.resolve_types` which can be used to resolve forward declarations in classes created using `__annotations__`
Fixes#265
* Fix flake8 and doctest
* Missed one
* Fix lint
* Address CR comments
Add to stubs
Make it a decorator, because why not?
* Fix test
* Rerun-tests please
* Rerun-tests please
* Fix another
* Fix lint
Co-authored-by: David Euresti <david@zapgram.com>
* 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
* Add control to generate __[sg]etstate__
Pass *getstate_setstate* to attr.s to control the generation. Mostly
interesting for disabling it in slotted classes.
Fixes #512,#513
* Update glossary.rst
* Implement auto_detect
Fixes#324
* Add test demonstrating total_ordering
* Ensure the order of applying total_ordering does not matter
* Warn if a method is missing
* Revert "Warn if a method is missing"
This reverts commit 590ef43458040e0a1b9f3644ba22b4229f7d6990.
* Add stern warning that nobody will read
* from parsyfiles development (https://github.com/smarie/python-simple-file-collection-parsing-framework):
* added new 'chain' validator to allow users to chain their custom validators with, for example, 'instance_of'
* added utility methods to get the declared attribute type (by inspecting its validators) and to check if it is optional
* from parsyfiles development (https://github.com/smarie/python-simple-file-collection-parsing-framework):
* added tests
* fixed bug with optional validator to pass tests :)
* from parsyfiles development (https://github.com/smarie/python-simple-file-collection-parsing-framework):
* completed doc api.rst
* small mod in tests
* Fixed issue with empty cell in closure when slots are used. Fixed#589
* Removed api.rst mods erroneously injected from another branch.
* Removed api.rst mods erroneously injected from another branch.
* noqa so that flake8 is happy
* Fixed lint error
* Added towncrier changelog entry
* Attempt to fix linter error
* Update tests/test_slots.py
* Last lint fix
* Update changelog.d/590.change.rst
Co-Authored-By: Hynek Schlawack <hs@ox.cx>
* Added extensive doc in the new test
* Update tests/test_slots.py
* last lint error
Co-authored-by: Sylvain MARIE <sylvain.marie@se.com>
Co-authored-by: Hynek Schlawack <hs@ox.cx>
* 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>
* Add xfailing test for frozen/cache_hash issue
This is a failing test for GH issue #611, with the xfail decorator to be
removed when the issue is fixed.
* Fix incompatibility between frozen and cache_hash
Fixes GH issue #611: serialization of a class with frozen=True and
cache_hash=True will now succeed rather than raising a
FrozenInstanceError.
Co-authored-by: Hynek Schlawack <hs@ox.cx>
* Add attr.__version_info__
This allows users to check for features and avoid deprecation warnings without
breaking backward compatibility.
* Add newsfragment
* Stay ASCII
* Typo
* Add stubs for _version.py
* Address David's feedback
* Handle PY2 better in comparability test
* drop the ing
* 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!
* matches
* added flags pass-through, and multiple function options; defaults to fullmatch
* move logic from validate to constructor
* cleaned up default args / fullmatch emulation
* fixed meta validator
* cleaned up default args / fullmatch emulation
* test cleanup
* versionadded tag
* added changelog entry
* cleaned up type checks, added to api docs and pyi type signature
* black formats
* black formatting
* 100% test coverage
* added example usage of matches_re to docs
* fixing py2 swallow type error and wrong quote in doctest
* explicit tests for all possible func args
* pragma no branch to get coverage 100%
* 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
* 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
Use bound type variables for iterables and mappings of the validated item types, so mypy does not erroneously require both the iterable attribute validated by deep_iterable and the item type validated by the first argument of deep_iterable to have the same type. This fixes#531.
* Pure-Python approach to closure cell rewriting
* Re-add mistakenly removed @skipif(PYPY)
* no-cover the 'should be impossible' lines and the functions that are only defined for their side effects on closure cells
* add new validators from #425 to validators.__all__
* add test for each validator, verifying that it is in validators.__all__
* add changelog entry for #517
* apply autolinting
* Make module path absolute
* Remove code and tests related to deprecated 'convert' kwarg
* Updated documentation, added changelog.d entry
* Fix attrib signature in docstring
* Update docstring version number for removal of 'convert' kw argument in attrib
* Implement first class exception support
Fixes#368
* Ensure single-attrib classes work too
cf https://github.com/python-attrs/attrs/pull/500#pullrequestreview-201913569
* Call into BaseException to initialiaze self.args
* Leave __str__ alone since we upcall
Based on Python pizza hallway feedback by @ambv.
* remove stray stage
* nope
* Clarify documentation for hashing
Makes clear that hashable objects need to be deeply immutable, in
practice even if not in theory.
Closes#503 .
* Use simple past tense in docs
* 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
* Allow init=False attributes to follow kw_only attributes
Closes#450
* Fix changelog typo
* Update reference text for exception message
* Remove type annotations from tests
* Fix long docstring lines
* Add test with literal default
* initial implementation of deep validators for iterables and dictionaries
* initial implementation of is_callable validator
* add versionadded for deep validators
* add versionadded for is_callable validator
* add tests for is_callable validator
* tweak _DeepIterable repr
* add tests for deep_iterable
* add to _DeepDictionary an initial validation that the top-level value is in fact a dictionary
* add tests for deep_dictionary validator
* apply precommit hooks
* refactor deep_dictionary to deep_mapping with optional mapping validator
* move is_callable validator up in module to allow deep validators to use it
* complete conversion from "deep dictionary" to "deep mapping"
* add changelog.d entry for #425
* fix rst formatting and normalize to semantic newlines
* add "instance_of", "deep_iterable", and "deep_mapping" validators to docs/api.rst
* add "serve-docs" tox environment to preview rendered sphinx docs
* bump versionadded for is_callable and deep validators to 18.3.0
* linting cleanup
* Revert "add "serve-docs" tox environment to preview rendered sphinx docs"
This reverts commit a2df89b788fdc31b54e604095c166b6a37c56f19.
* fix error message broken in linting fix
* Add weakref parameter to attr.s()
#325
* Add weakref to simple_classes() strategy
* Rename changelog file with actual PR (420.change.rst)
* Add test_weakref_does_not_add_a_field()
* Add docstrings to new weakref tests
* Add missing blank line
* Correct weakref handling of __weakref__ attributes or an inherrited slot
* Correct typos and terms
* Rename to weakref_slot
* Parametrize more tests against weakref_slot True/False to expose trouble
* Check if __weakref__ has been inherited via a __dict__
* Correct copy/pasted comment
* Change weakref_slot default to True
* Tidy and correct weakref -> weakref_slot
* 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
* Added support for keyword-only attributes. Closes#106, and closes#38
(Rebases #281)
Co-authored-by: Alex Ford <fordas@uw.edu>
* Add `attr.s`-level `kw_only` flag.
Add `kw_only` flag to `attr.s` decorator, indicating that all class
attributes should be keyword-only in __init__.
Minor updates to internal interface of `Attribute` to support
evolution of attributes to `kw_only` in class factory.
Expand examples with `attr.s` level kw_only.
* Add `kw_only` to type stubs.
* Update changelog for rebased PR.
Hear ye, hear ye. A duplicate PR is born.
* Tidy docs from review.
* Tidy code from review.
* Add explicit tests of PY2 kw_only SyntaxError behavior.
* Add `PythonToOldError`, raise for kw_only on PY2.
* `Attribute._evolve` to `Attribute._assoc`.
self._cls_dict["__weakref__"] holds a reference to self._cls, preventing
self._cls from being released after the new, slots-enabled class is
returned.
Fixes#407
* Improve error for in_(a_string) with a non-string value
* Tighten exception handling and test description
* Improve changelog for Hynek
* Final changelog edit
* Add narrative chapter on initialization
* Be more explicit about defining validators both ways
* Stress that the name of default/validator != attr name
* Mention nested schemas
* Explain handling of private attributes
* Add another consequence of _ stripping
* Stress that nothing should overwrite attributes on class body
* Better wording
* typo
* Dedup examples
* Address review feedback
* Add newsfragments
* Annotate __init__ with type hints
This just adds the annotations found at run-time to the
`__annotations__` attribute of the created `__init__` function
Fixes#249
* More tests. Add return annotation
* Documentation
* This is not markdown
* Retain order if these or make_class are passed an ordered dict
Fixes#339
* Add newsfragment
* Another newsfragment
Fixes#300
* Docs and change tags
* Disable coverage and explain why
* PyPy has ordered dicts too
* Import OrderedDict only when necessary
* Make cell setting completely best effort
We just try, catch any exception and warn if it doesn't work on a Python 3.
Should cover edge cases such as Jython or GAE.
Fixes#321
* Add news fragment
* Typing is hard yo
* Make _CountingAttr empty metadata unique
Issue #278
* Correct st.none().map() to st.builds()
* Add 'real' and 'force coverage' tests for not None metadata
* Add changelog for pr 280
* Correct import order in tests/test_make.py
* Add back coverage force test
* Remove debug print from test/utils.py
* Fix and accelerate generated __hash__ methods
We now create a method like we do for __init__ and hash also the class of the
instance.
* Add/fix news fragments
* Hash random numbers instead of the actual class
* Even simpler: let's hash the unique filename
Or rather it's hash, because hashing ints is very fast.
* 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
* Add support for passing a type to attr.ib() and gathering the type from PEP526-style annotations.
* Address review notes.
* More review notes.
* A few more review changes.
* Quick final fix to the changelog.