-
-
Notifications
You must be signed in to change notification settings - Fork 372
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] First class type support #215
Comments
+1 |
This would be awesome! Is the goal to enable type checking within attrs itself? and to support types as listed in typing.py? There's a few caveats that we've discovered, diving in. 1 is there's no standardized type checking behavior for collections in typing. From my understanding, this is still an area that needs more work: Most people have been writing their own type validation libraries to compensate: https://pypi.python.org/pypi/typeguard All in all, I'm a huge fan of this direction. Just wondering what the choice is for type checker. |
We don’t have concrete plans yet! Mostly because we want to make types & serialization first class concepts in attrs while doing this. :) |
Wait, wrong ticket! :) Yeah, no still no idea yet! |
I have a couple thoughts on this, if you're looking for ideas. The type parameters should probably be equivalent to adding two behavior: validate and convert:
This works pretty well for primitive types. There's some nastiness with more complex types, which attrs probably shouldn't solve. For example, I'd expect to be able to do something like:
but these would fail, because the datetime constructor takes none of these. I would argue probably just not handling this case, and letting people override with whatever complex converters they prefer:
The other part is using or supporting typing modules. this will require some choices in behavior (e.g. validating types recursively, or just validating the top level collection for collection types). I prefer recursive validation and conversion, personally. |
Yes, feel free to dump all your thoughts. The more input we get beforehand, the less mistakes we’re likely to make. :) |
OK, let's split the proposal into sub-features for easier commenting. Create the type metadata
Presumably
So basically like #214, but with the type argument for older Pythons. So what do we do with this data?Static checksMy personal opinion is that static analysis is the future here. This means writing a MyPy plugin (which coincidentally I kinda promised to do, but I won't get around to until my main vacation at the end of July, probably), and maybe getting other vendors (flake8, pylint, pycharm...) in this space to cooperate too. Static analysis has two major advantages. The first is that some types are impossible or exceedingly difficult to check for in runtime - think
Even if you have simple type annotations, without generics, the This isn't me getting into static vs dynamic typing, just stating the fact that static types are a tool with advantages over doing it in runtime. We're getting them in Python and it's exciting! We will still need validators since validators can check the values of types, and MyPy can't. So you will always need a validator to ensure your int is positive, for example. Now, as I mentioned, this is probably the future. We can't really rely on this today since MyPy doesn't even support the easy cases of attrs classes. Runtime checksThere is still value in runtime checking, of course. Not everyone will be able or willing to run MyPy over their code base, or maybe you want checks in the REPL, so us having a nice API for this would be good. This will require a little logic in our type validation, since not all types from The runtime type checks should be opt-in. I'm not sure if the opt-in should be on the class level (I feel like we'd need an opt-out at the attribute level) or at the attribute level, or both. Let's experiment with some ideas for attribute-level opt-in.
|
I agree that at least, introducing the type attribute and doing nothing but attaching it to the field would be great. It's a fantastic building block to build off of. It would also be great to fold in the type definition into the attr.ib object, if possible, so
and
are functionally equal (if both are declared, attr.ib(type=foo) could take precedence). I know there's an existing PR around attrs support for MyPy, so that'll handle the static checks at some point. Personally, I'm more interested in the dynamic checks. I'd like to integrate it as a serializer for an API validation library I've been working on (http://transmute-core.readthedocs.io/en/latest/), and attrs has a great philosophy with performance as a feature. Regarding the way validation is declared, validate_type seems syntactically the nicest. Although the complexities of type validation is definitely a larger ordeal. A lot of choices as @Tinche points out. validate_type could do shallow or deep validation, and that's control you may want to leave to the user. Providing simple integrations with existing runtime type checking / conversion tooling might be better. e.g. typeguard or cattrs. |
I'm drinking Aperol Spritz by Lake Como right now but briefly:
More when I'm back after EP. Although I may sprint on it. |
Turns out I didn’t and went to San Marino instead! Anyhow, so far we seem to have a consensus that:
Correct? So far that seems rather straightforward. I’d just like to make 100% sure that it won’t paint us in a corner re: deserialization? I’d like explicit comments from the two who built deserialization on top of attrs: @glyph and @Tinche |
I'm 100% on board with what you wrote FWIW. |
FYI this is a very busy weekend for me but this is definitely in my queue to look at soon. |
Cool, but don't overthink it. This is but a first building block. :) |
👊 @glyph (that’s a fist bump, not an attempt of intimidation thru violence :)) |
That (type attribute) seems like a solid first step. |
@Tinche I'm thinking about your But I'm wondering if it could also have global (ew?) switch of some sort. Since type validation, as you note, can be expensive, it's nice to do it statically if possible, but… The runtime case I'd want to check is when unit testing, I think, just in case the static analysis toolchain is missing something. At least today, there are a lot of cases where So I think there's a use case for: do validation when unit testing but not otherwise. Perhaps I'm asking for a more fine-grained version of |
Personally I'd rather have validation turned on all the time by default; I care more about correctness than speed. I want to rely on this to validate types when constructing them from wire formats. On PyPy, these isinstance checks will be no-opped out on the loops where they pass anyway, won't they? |
@wsanchez fun fact: the reason behind @glyph I agree on correctness > speed, however adding an implicit handbrake like this makes me uneasy. The big question is: has static type checking a future in Python or not? IOW: there will be a I personally tend to |
@glyph I'm mostly in your camp, just trying to be sympathetic to the argument that sometimes, the validation is expensive overkill. That is, I might have a model object that, when I deserialize to it from JSON, I totally wan't validation, but when I read it from the database that I'm confident only have valid data, I might want to skip the validation, because I can test that pretty thoroughly. I don't know what magic PyPy does to be smarter than me, and perhaps I should never optimize anything because PyPy will always do it better. Though I can't use PyPy yet, because at this point, I'm entered the "if it's not >=Py3.6, it's BULLSHIT" phase of my life. :-) |
It's a good phase of life – enjoying not myself too. In seriousness: unless someone comes up with a magical solution to validating types that goes beyond isinstance and doesn't introduce a new dependency, the default is settled. |
I am using def appropriate_type(T):
if isunion(T):
return tuple(appropriate_type(arg) for arg in T.__args__)
if issubclass(T, typing.List):
return list
if issubclass(T, typing.Dict):
return dict
if issubclass(T, typing.Set):
return set
return T |
FWIW, the relevant function seems to be https://github.com/agronholm/typeguard/blob/master/typeguard.py#L348 Also the pkg is by @agronholm and I have a hunch he may be open to persuasion to donate a validator to us. :) I’m still against adding a handbrake by default – it just feels wrong. :| |
How would you feel if we added an alternate, non-type-checked classmethod constructor? |
a nocheck argument is a nice piece in general. great to just instantiate things as fast as possible if you're really confident the data is valid. I'm +1 for no default type checking. It's a big change from the existing assumption that the validation is explicit, and I really like attrs because it's a nice syntax around creating classes, and keeps the classes lean. |
If you don't want this type of type checking, don't pass |
@glyph I thought the idea was that x: int = attribute() # Implies type=int |
That's certainly the plan. Only open question to me is whether it makes any sense to artificially set |
This is the first step, the second being copying from |
Please don't modify |
Modifying |
The examples I've seen so far would forego the annotations and instead pass the type off to |
I just added a PR for the parts we all seem to agree on. Pop on by and let me know what you think. |
Two more thoughts:
For convenience, we could combine all 3 in one go by providing a dict with each of the type-aware keyword arguments: import attr
from attr import use_type
@attr.s
class C:
x: int = attr.ib(**use_type) |
Sounds good to me. |
FTR, the reason why I’m thinking about modifying @attr.s
class C(object):
x = attr.ib(type=int) # type: int Although I concur, that it should be probably solved in mypy. The use_type magic goes a bit too far for attrs proper but we can revisit that topic once the groundwork is done. |
Static analysis and type annotations are pretty new, so before proceeding I should make a few non-obvious things clear so that we're all on the same page:
Getting back to the original point: we can avoid the need for type comments in python 2.7 by providing pyi stubs with an from typing import Any, Mapping, Type, TypeVar, overload
T = TypeVar('T')
@overload
def attr(default: Any = ..., metadata: Mapping = ...) -> Any: ...
@overload
def attr(default: Any = ..., metadata: Mapping = ..., type: Type[T] = ...) -> T: ... This says that if That makes clear to static type-checkers that in your example @attr.s
class C(object):
x = attr.ib(type=int) |
Hm, that actually looks quite clever! |
I'll throw my 2c in here -- I've written a little PoC library a while ago that codegens runtime type checkers in an efficient fashion given the type annotations: http://github.com/aldanor/typo. It can handle most basic type classes, but also things like Compared to other similar libraries, specifying It gets pretty complicated with generic type vars though (specifically, with union-type ones) since you have to generate some pretty complicated code to deal with generics inside sum-types (not going into further details but it's fairly hairy). If you ban generics inside sum-types then it becomes very simple and straightforward -- e.g. constraints like Maybe some pieces could be reused or partially reused in here, saving everyone a bit of time :) |
We have recently merged generic type support, maybe you'd like to play with it a bit and give feedback? I'm don't think we'll rush adding the actual checking anytime soon. Maybe we'll even point at external solution, so feel free to experiment. |
First class support is in thanks to #239, we can open new issues on what to do with those type now. |
I was trying to find https://github.com/aldanor/typo today but instead I ran across https://github.com/RussBaz/enforce which looks like it may be a fairly full-featured version of the same thing. |
There is also https://github.com/Stewori/pytypes
May the best project win.
…On Tue, Nov 14, 2017 at 4:37 PM Glyph ***@***.***> wrote:
I was trying to find https://github.com/aldanor/typo today but instead I
ran across https://github.com/RussBaz/enforce which looks like it may be
a fairly full-featured version of the same thing.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#215 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAD3ExNEMEFKt-RbcCG4I_VwqdxFp-oEks5s2jI6gaJpZM4OFBOJ>
.
|
167: Scheduled weekly dependency update for week 46 r=mithrandi ## Updates Here's a list of all the updates bundled in this pull request. I've added some links to make it easier for you to find all the information you need. <table align="center"> <tr> <td><b>attrs</b></td> <td align="center">17.2.0</td> <td align="center">»</td> <td align="center">17.3.0</td> <td> <a href="https://pypi.python.org/pypi/attrs">PyPI</a> | <a href="https://pyup.io/changelogs/attrs/">Changelog</a> | <a href="http://www.attrs.org/">Homepage</a> </td> <tr> <td><b>cryptography</b></td> <td align="center">2.1.2</td> <td align="center">»</td> <td align="center">2.1.3</td> <td> <a href="https://pypi.python.org/pypi/cryptography">PyPI</a> | <a href="https://pyup.io/changelogs/cryptography/">Changelog</a> | <a href="https://github.com/pyca/cryptography">Repo</a> </td> <tr> <td><b>hypothesis</b></td> <td align="center">3.33.0</td> <td align="center">»</td> <td align="center">3.37.0</td> <td> <a href="https://pypi.python.org/pypi/hypothesis">PyPI</a> | <a href="https://pyup.io/changelogs/hypothesis/">Changelog</a> | <a href="https://github.com/HypothesisWorks/hypothesis/issues">Repo</a> </td> </tr> </table> ## Changelogs ### attrs 17.2.0 -> 17.3.0 >### 17.3.0 >------------------- >Backward-incompatible Changes >^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >- Attributes are not defined on the class body anymore. > This means that if you define a class ``C`` with an attribute ``x``, the class will *not* have an attribute ``x`` for introspection anymore. > Instead of ``C.x``, use ``attr.fields(C).x`` or look at ``C.__attrs_attrs__``. > The old behavior has been deprecated since version 16.1. > (`253 <https://github.com/python-attrs/attrs/issues/253>`_) >Changes >^^^^^^^ >- ``super()`` and ``__class__`` now work on Python 3 when ``slots=True``. > (`102 <https://github.com/python-attrs/attrs/issues/102>`_, `226 <https://github.com/python-attrs/attrs/issues/226>`_, `269 <https://github.com/python-attrs/attrs/issues/269>`_, `270 <https://github.com/python-attrs/attrs/issues/270>`_, `272 <https://github.com/python-attrs/attrs/issues/272>`_) >- Added ``type`` argument to ``attr.ib()`` and corresponding ``type`` attribute to ``attr.Attribute``. > This change paves the way for automatic type checking and serialization (though as of this release ``attrs`` does not make use of it). > In Python 3.6 or higher, the value of ``attr.Attribute.type`` can alternately be set using variable type annotations > (see `PEP 526 <https://www.python.org/dev/peps/pep-0526/>`_). (`151 <https://github.com/python-attrs/attrs/issues/151>`_, `214 <https://github.com/python-attrs/attrs/issues/214>`_, `215 <https://github.com/python-attrs/attrs/issues/215>`_, `239 <https://github.com/python-attrs/attrs/issues/239>`_) >- The combination of ``str=True`` and ``slots=True`` now works on Python 2. > (`198 <https://github.com/python-attrs/attrs/issues/198>`_) >- ``attr.Factory`` is hashable again. (`204 > <https://github.com/python-attrs/attrs/issues/204>`_) >- Subclasses now can overwrite attribute definitions of their superclass. > That means that you can -- for example -- change the default value for an attribute by redefining it. > (`221 <https://github.com/python-attrs/attrs/issues/221>`_, `229 <https://github.com/python-attrs/attrs/issues/229>`_) >- Added new option ``auto_attribs`` to ``attr.s`` that allows to collect annotated fields without setting them to ``attr.ib()``. > Setting a field to an ``attr.ib()`` is still possible to supply options like validators. > Setting it to any other value is treated like it was passed as ``attr.ib(default=value)`` -- passing an instance of ``attr.Factory`` also works as expected. > (`262 <https://github.com/python-attrs/attrs/issues/262>`_, `277 <https://github.com/python-attrs/attrs/issues/277>`_) >- Instances of classes created using ``attr.make_class()`` can now be pickled. > (`282 <https://github.com/python-attrs/attrs/issues/282>`_) >---- ### hypothesis 3.33.0 -> 3.37.0 >### 3.37.0 >------------------- >This is a deprecation release for some health check related features. >The following are now deprecated: >* Passing :attr:`~hypothesis.HealthCheck.exception_in_generation` to > :attr:`~hypothesis.settings.suppress_health_check`. This no longer does > anything even when passed - All errors that occur during data generation > will now be immediately reraised rather than going through the health check > mechanism. >* Passing :attr:`~hypothesis.HealthCheck.random_module` to > :attr:`~hypothesis.settings.suppress_health_check`. This hasn't done anything > for a long time, but was never explicitly deprecated. Hypothesis always seeds > the random module when running given tests, so this is no longer an error > and suppressing it doesn't do anything. >* Passing non-:class:`~hypothesis.HealthCheck` values in > :attr:`~hypothesis.settings.suppress_health_check`. This was previously > allowed but never did anything useful. >In addition, passing a non-iterable value as :attr:`~hypothesis.settings.suppress_health_check` >will now raise an error immediately (it would never have worked correctly, but >it would previously have failed later). Some validation error messages have >also been updated. >This work was funded by `Smarkets <https://smarkets.com/>`_. >------------------- >### 3.36.1 >------------------- >This is a yak shaving release, mostly concerned with our own tests. >While :func:`~python:inspect.getfullargspec` was documented as deprecated >in Python 3.5, it never actually emitted a warning. Our code to silence >this (nonexistent) warning has therefore been removed. >We now run our tests with ``DeprecationWarning`` as an error, and made some >minor changes to our own tests as a result. This required similar upstream >updates to :pypi:`coverage` and :pypi:`execnet` (a test-time dependency via >:pypi:`pytest-xdist`). >There is no user-visible change in Hypothesis itself, but we encourage you >to consider enabling deprecations as errors in your own tests. >------------------- >### 3.36.0 >------------------- >This release adds a setting to the public API, and does some internal cleanup: >- The :attr:`~hypothesis.settings.derandomize` setting is now documented (:issue:`890`) >- Removed - and disallowed - all 'bare excepts' in Hypothesis (:issue:`953`) >- Documented the :attr:`~hypothesis.settings.strict` setting as deprecated, and > updated the build so our docs always match deprecations in the code. >------------------- >### 3.35.0 >------------------- >This minor release supports constraining :func:`~hypothesis.strategies.uuids` >to generate :class:`~python:uuid.UUID`s of a particular version. >(:issue:`721`) >Thanks to Dion Misic for this feature. >------------------- >### 3.34.1 >------------------- >This patch updates the documentation to suggest >:func:`builds(callable) <hypothesis.strategies.builds>` instead of >:func:`just(callable()) <hypothesis.strategies.just>`. >------------------- >### 3.34.0 >------------------- >Hypothesis now emits deprecation warnings if you apply >:func:`given <hypothesis.given>` more than once to a target. >Applying :func:`given <hypothesis.given>` repeatedly wraps the target multiple >times. Each wrapper will search the space of of possible parameters separately. >This is equivalent but will be much more inefficient than doing it with a >single call to :func:`given <hypothesis.given>`. >For example, instead of >``given(booleans()) given(integers())``, you could write >``given(booleans(), integers())`` >------------------- >### 3.33.1 >------------------- >This is a bugfix release: >- :func:`~hypothesis.strategies.builds` would try to infer a strategy for > required positional arguments of the target from type hints, even if they > had been given to :func:`~hypothesis.strategies.builds` as positional > arguments (:issue:`946`). Now it only infers missing required arguments. >- An internal introspection function wrongly reported ``self`` as a required > argument for bound methods, which might also have affected > :func:`~hypothesis.strategies.builds`. Now it knows better. >------------------- That's it for now! Happy merging! 🤖
161: Scheduled weekly dependency update for week 46 r=mithrandi ## Updates Here's a list of all the updates bundled in this pull request. I've added some links to make it easier for you to find all the information you need. <table align="center"> <tr> <td><b>attrs</b></td> <td align="center">17.2.0</td> <td align="center">»</td> <td align="center">17.3.0</td> <td> <a href="https://pypi.python.org/pypi/attrs">PyPI</a> | <a href="https://pyup.io/changelogs/attrs/">Changelog</a> | <a href="http://www.attrs.org/">Homepage</a> </td> <tr> <td><b>cryptography</b></td> <td align="center">2.1.2</td> <td align="center">»</td> <td align="center">2.1.3</td> <td> <a href="https://pypi.python.org/pypi/cryptography">PyPI</a> | <a href="https://pyup.io/changelogs/cryptography/">Changelog</a> | <a href="https://github.com/pyca/cryptography">Repo</a> </td> <tr> <td><b>lxml</b></td> <td align="center">4.1.0</td> <td align="center">»</td> <td align="center">4.1.1</td> <td> <a href="https://pypi.python.org/pypi/lxml">PyPI</a> | <a href="https://pyup.io/changelogs/lxml/">Changelog</a> | <a href="http://lxml.de/">Homepage</a> | <a href="https://bugs.launchpad.net/lxml">Bugtracker</a> </td> <tr> <td><b>pytz</b></td> <td align="center">2017.2</td> <td align="center">»</td> <td align="center">2017.3</td> <td> <a href="https://pypi.python.org/pypi/pytz">PyPI</a> | <a href="http://pythonhosted.org/pytz">Homepage</a> | <a href="http://pythonhosted.org/pytz/">Docs</a> </td> </tr> </table> ## Changelogs ### attrs 17.2.0 -> 17.3.0 >### 17.3.0 >------------------- >Backward-incompatible Changes >^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >- Attributes are not defined on the class body anymore. > This means that if you define a class ``C`` with an attribute ``x``, the class will *not* have an attribute ``x`` for introspection anymore. > Instead of ``C.x``, use ``attr.fields(C).x`` or look at ``C.__attrs_attrs__``. > The old behavior has been deprecated since version 16.1. > (`253 <https://github.com/python-attrs/attrs/issues/253>`_) >Changes >^^^^^^^ >- ``super()`` and ``__class__`` now work on Python 3 when ``slots=True``. > (`102 <https://github.com/python-attrs/attrs/issues/102>`_, `226 <https://github.com/python-attrs/attrs/issues/226>`_, `269 <https://github.com/python-attrs/attrs/issues/269>`_, `270 <https://github.com/python-attrs/attrs/issues/270>`_, `272 <https://github.com/python-attrs/attrs/issues/272>`_) >- Added ``type`` argument to ``attr.ib()`` and corresponding ``type`` attribute to ``attr.Attribute``. > This change paves the way for automatic type checking and serialization (though as of this release ``attrs`` does not make use of it). > In Python 3.6 or higher, the value of ``attr.Attribute.type`` can alternately be set using variable type annotations > (see `PEP 526 <https://www.python.org/dev/peps/pep-0526/>`_). (`151 <https://github.com/python-attrs/attrs/issues/151>`_, `214 <https://github.com/python-attrs/attrs/issues/214>`_, `215 <https://github.com/python-attrs/attrs/issues/215>`_, `239 <https://github.com/python-attrs/attrs/issues/239>`_) >- The combination of ``str=True`` and ``slots=True`` now works on Python 2. > (`198 <https://github.com/python-attrs/attrs/issues/198>`_) >- ``attr.Factory`` is hashable again. (`204 > <https://github.com/python-attrs/attrs/issues/204>`_) >- Subclasses now can overwrite attribute definitions of their superclass. > That means that you can -- for example -- change the default value for an attribute by redefining it. > (`221 <https://github.com/python-attrs/attrs/issues/221>`_, `229 <https://github.com/python-attrs/attrs/issues/229>`_) >- Added new option ``auto_attribs`` to ``attr.s`` that allows to collect annotated fields without setting them to ``attr.ib()``. > Setting a field to an ``attr.ib()`` is still possible to supply options like validators. > Setting it to any other value is treated like it was passed as ``attr.ib(default=value)`` -- passing an instance of ``attr.Factory`` also works as expected. > (`262 <https://github.com/python-attrs/attrs/issues/262>`_, `277 <https://github.com/python-attrs/attrs/issues/277>`_) >- Instances of classes created using ``attr.make_class()`` can now be pickled. > (`282 <https://github.com/python-attrs/attrs/issues/282>`_) >---- ### lxml 4.1.0 -> 4.1.1 >### 4.1.1 >================== >* Rebuild with Cython 0.27.3 to improve support for Py3.7. That's it for now! Happy merging! 🤖
118: Update attrs to 17.3.0 r=mithrandi There's a new version of [attrs](https://pypi.python.org/pypi/attrs) available. You are currently using **17.2.0**. I have updated it to **17.3.0** These links might come in handy: <a href="https://pypi.python.org/pypi/attrs">PyPI</a> | <a href="https://pyup.io/changelogs/attrs/">Changelog</a> | <a href="http://www.attrs.org/">Homepage</a> ### Changelog > >### 17.3.0 >------------------- >Backward-incompatible Changes >^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >- Attributes are not defined on the class body anymore. > This means that if you define a class ``C`` with an attribute ``x``, the class will *not* have an attribute ``x`` for introspection anymore. > Instead of ``C.x``, use ``attr.fields(C).x`` or look at ``C.__attrs_attrs__``. > The old behavior has been deprecated since version 16.1. > (`253 <https://github.com/python-attrs/attrs/issues/253>`_) >Changes >^^^^^^^ >- ``super()`` and ``__class__`` now work on Python 3 when ``slots=True``. > (`102 <https://github.com/python-attrs/attrs/issues/102>`_, `226 <https://github.com/python-attrs/attrs/issues/226>`_, `269 <https://github.com/python-attrs/attrs/issues/269>`_, `270 <https://github.com/python-attrs/attrs/issues/270>`_, `272 <https://github.com/python-attrs/attrs/issues/272>`_) >- Added ``type`` argument to ``attr.ib()`` and corresponding ``type`` attribute to ``attr.Attribute``. > This change paves the way for automatic type checking and serialization (though as of this release ``attrs`` does not make use of it). > In Python 3.6 or higher, the value of ``attr.Attribute.type`` can alternately be set using variable type annotations > (see `PEP 526 <https://www.python.org/dev/peps/pep-0526/>`_). (`151 <https://github.com/python-attrs/attrs/issues/151>`_, `214 <https://github.com/python-attrs/attrs/issues/214>`_, `215 <https://github.com/python-attrs/attrs/issues/215>`_, `239 <https://github.com/python-attrs/attrs/issues/239>`_) >- The combination of ``str=True`` and ``slots=True`` now works on Python 2. > (`198 <https://github.com/python-attrs/attrs/issues/198>`_) >- ``attr.Factory`` is hashable again. (`204 > <https://github.com/python-attrs/attrs/issues/204>`_) >- Subclasses now can overwrite attribute definitions of their superclass. > That means that you can -- for example -- change the default value for an attribute by redefining it. > (`221 <https://github.com/python-attrs/attrs/issues/221>`_, `229 <https://github.com/python-attrs/attrs/issues/229>`_) >- Added new option ``auto_attribs`` to ``attr.s`` that allows to collect annotated fields without setting them to ``attr.ib()``. > Setting a field to an ``attr.ib()`` is still possible to supply options like validators. > Setting it to any other value is treated like it was passed as ``attr.ib(default=value)`` -- passing an instance of ``attr.Factory`` also works as expected. > (`262 <https://github.com/python-attrs/attrs/issues/262>`_, `277 <https://github.com/python-attrs/attrs/issues/277>`_) >- Instances of classes created using ``attr.make_class()`` can now be pickled. > (`282 <https://github.com/python-attrs/attrs/issues/282>`_) >---- *Got merge conflicts? Close this PR and delete the branch. I'll create a new PR for you.* Happy merging! 🤖
Where is the discussion about runtime automatic type checking happening? |
There is none so far. I believe a good first step would be to add generic class-wide validators ( |
Thanks. Shall we open a separate issue or re-open this one? |
I think a new one would be best. |
This is kind of part of #214 but it stands for itself too.
Something like:
ought to work.
Regardless of checking the type, the type information has to be accessible somewhere so we can have first-class deserialization support.
The text was updated successfully, but these errors were encountered: