-
-
Notifications
You must be signed in to change notification settings - Fork 374
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
pass bases keyword argument to make_class #152
pass bases keyword argument to make_class #152
Conversation
Allow make_class to subclass by using bases keyword argument. It would be useful to be able to do this when writing a framework with attrs.
Codecov Report
@@ Coverage Diff @@
## master #152 +/- ##
=====================================
Coverage 100% 100%
=====================================
Files 8 8
Lines 551 551
Branches 122 122
=====================================
Hits 551 551
Continue to review full report at Codecov.
|
Wellll, testing-wise you’ve lowered the code coverage. :) Before you spend more time coding: could you provide us with a practical example of what you want to achieve? That’s also something that should go into examples.rst if we admit this change. |
I coded up an example. I'd like to build a model where equality is defined by the attributes and properties being equal (equal key with equal values). This works to the specifications: import attr
class Base:
def __eq__(self, other):
defaults = dir(attr.make_class('None', {}))
keys = []
for attr_or_prop in [key for key in dir(self) if key not in defaults]:
keys.append(attr_or_prop)
return all([getattr(self, key) == getattr(other, key) for key in keys])
@attr.s(cmp=False)
class ModelOne(Base):
stuff = attr.ib(default='')
@attr.s(cmp=False)
class ModelSame(Base):
stuff = attr.ib(default='')
@attr.s(cmp=False)
class ModelDifferent(Base):
stuff = attr.ib(default='different!')
one = ModelOne()
same = ModelSame()
different = ModelDifferent()
assert one == same
assert one != different
assert same != different Now I'd like to do the same behavior by making the class dynamically with attributes = {
'stuff': attr.ib('')
}
# cannot use subclass, what do do?
one = attr.make_class('One', attributes)
same = attr.make_class('Same', attributes)
assert one == same # AssertionError By passing bases I can do this, but is there a cleaner way of doing this? |
Right. So the new functionality has to be tested to make sure it works and doesn’t break in the futures. Simply write a test that creates a class that uses a custom subclass and you’re golden. I would assume it also can be simplified by pulling the Also you’re gonna want everyone to know about that new feature so you need to
Feel free to check out https://github.com/python-attrs/attrs/blob/master/CONTRIBUTING.rst if you’re unsure how to do that! Thanks! |
As far as using |
…f/attrs into make_class_with_bases
Submitted for your approval :) |
Thank you for your contribution! I’ve added some minor fixes I didn’t want to boss you around for. :) |
Currently attr is hard-coded to use
(object,)
as the bases argument in thetype()
call. Adding bases as keyword argument would allowattr.make_class
to be used in more situations (where you have to use a subclass, and you have to make a class dynamically).Testing-wise, not sure if another test is needed for this well-understood feature; I ran pytest with this modification and it passed all of them.