Disable leading underscore removal in attrs auto-generated init method signature - python-attrs

attr strips leading underscore from attribute names for the generated __init__ method . Is there a way to override that for a particular attribute, short of disabling auto-generated initialization method for the class entirely?
I'd like to use attr class to represent MongoDB documents, which in Python are dictionaries with the _id key to record the unique id. I was hoping to be able to have a from_db(cls, doc) class method that's little more than return cls(**doc), but the presence of _id causes "TypeError: init() got an unexpected keyword argument '_id'". Right now, I work around it by declaring `_id: attr.ib(init=False, default=None), and having:
#classmethod from_db(cls, doc):
_id = doc["_id"]
del(doc["_id"])
obj = cls(**doc)
obj._id = _id
return obj
but that seems really klugey. Is there a better way?

Currently not possible, sorry.
See:
https://github.com/python-attrs/attrs/issues/391
https://github.com/python-attrs/attrs/issues/619
Long-term you'll probably run into more complicated exceptions and then tools like cattrs make more sense.

Related

Better way to assign a value with nullable field in dart

Is there a better way to do this?
Assignment(
dueAt: json['due_at'] == null ?
null :
DateTime.parse(json['due_at']).toLocal()
)
The attribute "dueAt" in Assignment class can be null and i need to parse the string of json['due_at'] to a DateTime, but json['due_at'] can be null too.
Is not really a problem right now but seems noisy and repetitive.
First and foremost, it looks like you're writing JSON serialization code by hand. Your life will be much easier and less bug-prone if you let a library do this instead. json_serializable is very simple and powerful and 100% worth looking into.
However, this pattern is still common outside of json code.
You could also consider writing an extension method for Object? that behaves like the Kotlin standard library's let function (https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/let.html)
You can then use Dart's ?. syntax to handle the rest of the logic:
// extension on T rather than Object? to maintain type information
extension Example<T> on T {
R let<R>(R Function(T) function) => function(this);
}
This just applies a given function to this, which isn't incredibly useful on it's own, but allows the use of ?.:
final DateTime? dueAt = json['due_at']?.let(DateTime.parse);
If json['due_at'] evaluates to null, the ?. operator short-circuits, and dueAt is set to null. Otherwise, it evaluates to DateTime.parse(json['due_at']).
Or, you could just use package:kt_dart which ports much of the Kotlin standard library to Dart
In this particular case you may want to use tryParse instead of parse. If dueAt is of type DateTime? you can simply call:
Assignment( dueAt: DateTime.tryParse(json['due_at'])?.toLocal() );
Be aware though that tryParse will return null for any invalid date string (be it null or an improperly formatted string). This may or may not be desired behavior depending on your intended use.

HashMap no instance key

What is wrong with my code?
widget.woList is this datatype List<HashMap<int, ABC>>()
for (var i in widget.woList) {
print(i.toString());
}
By printing above code, I get
{5838: ABC(pid: 84201,userId: 545)}
But when I want to get only key ( print(i.key.toString());), I get below error:
Class '_HashMap<int, ABC>' has no instance getter 'key'.
Receiver: Instance of '_HashMap<int, ABC>'
Tried calling: key
I think you need to loop through the HashMap as well:
for (HashMap<int, ABC> i in list) {
i.forEach((key, value) {
print(key.toString());
print(value.toString());
});
}
Make sure you typo the "i" variable in the for with HashMap<int, ABC> to get autocompletes from your IDE.
The analyzer should give an error in your case since a Map does not contain any property with the name key. Instead the name is keys which return a Iterable of keys in the map:
https://api.dart.dev/stable/2.8.1/dart-core/Map/keys.html
A map can contain multiple keys but if you know there are only one key in the map you can do something like: i.keys.first.toString(). But if there are multiple keys you need to loop through them.
I will recommend you use auto completion in your IDE when programming in Dart and make use of the analyzer. By using the tools the SDK provides, it is much easier to browse what properties and methods there are in each class together with the documentation. And since Dart can figure out the type of lots of variables automatically, you can use the IDE to also identify the type of each variable without even running the program.

Is there a way to overwrite the `{ }` object?

I'm trying to make all Hashes in my program be ActiveSupport::OrderedHash.
I can override the Hash.new constructor by ::Hash = ActiveSupport::OrderedHash but {}.class is still hash.
def {} gives me a syntax error.
It was recommended that this is a duplicate of this question, but I don't think that is the case. My question isn't about subclassing Hash, it's about overwriting the default { } => Hash constructor.
Hash literal {} is hard-coded in Ruby, and you cannot change it. {} will become a Hash. However, since Ruby's class can be modified, you can remove all unnecessary methods, constants, variables from Hash, and copy everything that is in ActiveSupport::OrderedHash into Hash.
There are only very few languages which allow you to overload literals (I only know of two: Ioke and Seph). Ruby is not one of them.
See also overloading Ruby's […] Array creation shorthand, Which method is invoked by […] in Ruby?, and How to intercept the call to constructor of class Hash?.

What parameters should be used for AbstractDeclarativeValidator.warning and error?

I have a working grammar on xtext, and am starting the validation of the code.
For this, I added a method in the validator xtext created for me.
Of course, when an expression isn't valid, I want to be able to give a warning on the given AST node.
I attempted the obvious:
#Check
public void testCheck(Expression_Multiplication m){
if(!(m.getLeft() instanceof Expression_Number)){
warning("Multiplication should be on numbers.",m.getLeft());
}
if(!(m.getRight() instanceof Expression_Number)){
warning("Multiplication should be on numbers.",m.getRight());
}
}
Without success, as Expression_Number extends EObject, but is not an EStructuralFeature.
warning(String message, EStructuralFeature feature)
There are many other prototypes for warning, but none that takes just a String and a Eobject. Using null or various values extracted from eContainingFeature logs an error, and sometimes shows the warning at the correct place anyway. Searching for examples, I found that the values were often coming from the statics fields of a class called Literals or ***Package, the one generated in the project contains EStructuralFeatures, but I have no idea of which one to use, or why I would need one of these.
So the question is:
How can I place a warning on a given AST element ?
The EStructuralFeature is the property of your AST. You'll find a generated EPackage class, which contains constants.
I guess in your case it is something like:
MyDslPackage.Literals.EXPRESSION_MULTIPLICATION__LEFT
and
MyDslPackage.Literals.EXPRESSION_MULTIPLICATION__RIGHT
I ended up using
private void warning(String text, EObject badAstNode){
// The -1 seems to come from a static member somewhere. Probably cleaner to
// name it, but I couldn't find it again.
warning(text,badAstNode,null,-1);
}
I have no idea about whether this is supposed to be the right way, but it seemed to work in the various cases I used it, and requires a minimal amount of state to be kept.

Regarding F# Object Oriented Programming

There's this dichotomy in the way we can create classes in f# which really bothers me. I can create classes using either an implicit format or an explicit one. But some of the features that I want are only available for use with the implicit format and some are only available for use with the explicit format.
For example:
I can't use let inline* (or let alone) inside an explicitly defined class.
The only way (that I know) to define immutable public fields (not properties*) inside an implicitly defined class is the val bla : bla syntax.
But there's a redundancy here. Since I'll end up with two copy of the same immutable data, one private, one public (because in the implicit mode the constructor parameters persist throughout the class existence)
(Not so relevant) The need to use attributes for method overloading and for field's defaults is rather off putting.
Is there anyway I can work around this?
*For performance reasons
EDIT: Turns out I'm wrong about both points (Thanks Ganesh Sittampalam & MichaelGG).
While I can't use let inline in both implicit & explicit class definition, I can use member inline just fine, which I assume does the same thing.
Apparently with the latest F# there's no longer any redundancy since any parameters not used in the class body are local to the constructor.
Will be gone in the next F# release.
This might not help, but you can make members inline. "member inline private" works fine.
For let inline, you can work around by moving it outside the class and explicitly passing any values you need from inside the scope of the class when calling it. Since it'll be inlined, there'll be no performance penalty for doing this.

Resources