Documentation: Added some UML for the control flow of the new code. R…

…elates to issue #3.
Due to the fact that the algorithm does not affect several classes but rather utilizes several functions I have decided to draw UML for the control flow. I believe that this adds the most to the understanding of the code.

Nice schema ! LGTM


get_class() and is_class() not returning class_name

v3.1.alpha.custom_build.5307043
The new class_name keyword doesn't affect the results of the methods for get_class() and is_class().
I noticed this earlier when encountering https://github.com/godotengine/godot/issues/21461, and it feels like maybe it might have been overlooked.  Not sure if it falls under bug or a feature request, or if maybe its even intentional and required.
It would be very useful to have these methods return the custom class types in certain situations.

This is expected, those methods get the name of the native class. It never worked with inner classes, which also have names.
Also, it's not clear what would this return if the script class don't have a name.

Also, it's not clear what would this return if the script class don't have a name.

I imagined that the class_name would override the native class name if you used it.  If you didn't it would work as usual.  At least in my mind extends Sprite would report being a "Sprite", but if you tagged on class_name CustomSprite, it would start reporting that it was a CustomSprite.

It never worked with inner classes, which also have names.

Good point.  First time looking at those in 3.1, it seems at least class_name isn't valid there, but at least not needed for is to compare with them.  So then it would only exclude them from being pushed up into the node list.
Since it would be enhancement request, and this makes sense to do, maybe inner classes would override in the same way with their given names.
The usefulness for having class_name appear over top the predecessor would be for some niche situations here and there, such as match and a few other things.  Nothing major, but seems like it would be expected to work this way.
match node.get_class():
	"Polygon2D": print("Poly")
	"Sprite": print("Sprite.")
	"AnimatedSprite": print("AnimSprite")
	"CustomSprite": print("My sprite.")

In the meanwhile I'm doing an override in every custom class to enable that behavior:
extends Node2D

class_name CustomClass

func get_class(): return "CustomClass"
func is_class(name): return name == "CustomClass" or .is_class(name)

func _ready():
	print(get_class())
	print(is_class("CustomClass"))
	print(is_class("Node2D"))

In my opinion it seems really odd to me that it doesn't return the custom types. It should definitely be documented though either way.

@vnen I'm glad you're weighing in on it for that reason.  These are just the "would be nice" thoughts of an end-user.  X)
I am curious though the nature of breakage.  I'm not sure if you mean for users going from 3.0 to 3.1, or something more on the internals side of things.

I would maybe go with get_class() -> returns base class name, and get_class_name() -> returns class_name?
If that's too confusing get_class() could be renamed to get_base_class(), and get_class() would then return class_name.

@PLyczkowski At least one way to determine an extended class currently is to do is_class("Node2D") say on a Sprite or something higher up.  The base class of most things (if not everything) I believe would just be Object.

I think it would make more sense to make the get_class return the class_name...
or create a "Type" structure like C# that return a bunch of packed info regarding the type of a given class.
get_type() -> Type:
then you could have:
type.class -> return the class_name
type.base_class -> returns the base class name
type.path -> returns the path to the gdscript where it is defined
...

Is there any plans for this? This would help tremendously, especially in debugging scenarii. And I guess it's probably not a huge thing to implement.

Here's a clumsy but actually easy/working solution for people using tools capable of mass replacing text across files using regexes, such as IntelliJ Idea.
Replace:
class_name (\w+)\s*\n(?!func get_class_name\(\))

with:
class_name $1
func get_class_name() -> String:
	return '$1'

Do test it on one file though in case your IDE/tool uses different regex syntax. But you can run this easily as many times as you want and it'll just add the missing ones.

I have an object that, when it enters the scene, it needs to connect relevant signals. I'd like to use class names in this process. To accomplish this I've overloaded get_class(). I expect I'll need to this soon too:
func is_class(name:String)->bool:
   return .is_class(name) or (get_class() == name)

This feels extremely clumsy. This functionality could be all contained with the class_name HelloWorld syntax but instead I have to add a overload of get_class() and is_class() to every class. This is 5 lines for what really should be 1.

A very useful use case for this would be in cross-scripting scenarios. Currently, when accessing GDScript scipts from C# code, as far as I can tell, there is no way to check the class name of a node. The workarounds mentioned here do not work, as you cannot overload C#'s IsClass/GetClass from GDScript code.
It is technically doable by using Call(), but that's gonna throw an exception if you try it on anything that doesn't implement the workaround and clashes with the var is class syntax that can be used on C# classes.

I was about to open a new issued but stumbled upon this one instead.
I confirm that it's a bit confusing to have the native class returned.
I had 2 classes : with class_name =  "Collectible" OR "Damageable",
Both are Area2D.
I needed to get which class they are at some point, but get_class() returned Area2D for both.
Which led me to get rid of class_name all together, and add variable 'name' instead.
I think the clearer approach would be to have get_class return class_name. But if it's not, it should return the parent class (Area2D in this specific case)

You can override the method inside the class:
def class_name():
    return "MyCustomName;"

you need to do this manually though! :(

Sure, but this is rather a workaround than a solution :)
It can be very error prone if you have a lot of classes, since you need to do this manually for each of them.
Cheers

Since Godot 4.0 is supposed to have a number of BC breaks anyway, making this behave as expected instead of the way it does now would be ideal.

Yeah, with 4.0 breaking compatibility, it's a good opportunity to make this much cleaner:
# my_node.gd
extends Node
class_name MyNode

# derived_node.gd
extends MyNode
class_name DerivedNode

# usage
my_node.get_class() # "MyNode"
my_node.get_base_class() # "Node"
my_node.get_native_class() # "Node"

derived_node.get_class() # "DerivedNode"
derived_node.get_base_class() # "MyNode"
derived_node.get_native_class() # "Node"

This provides you with full access to everything you need. Just need to have the get_base_class() method check for a script first, check if there's a base script, check if that script is a script class, i.e. a global class, and then return that name if all true, rather than just the native class. And if there is no script, then you revert back to using ClassDB.get_parent_class().

@willnationsdev Perfect

How is is_class() actually written in code, and why does it return false even when I both override get_class() and set class_name accordingly?

@mechPenSketch internal engine methods never call script methods (except for virtual methods which are intended to be overridden). So the script get_class() won't be called even if the engine uses it internally.

class_name doesn't change what class the script is so it also should not change what is returned by get_class().
If i had get_class() that was returning "bar" previously but now is returning "baz" i'd think that the class has changed. But it didn't - the script just started using class_name in order to make itself globally accessible or to be registered in the editor.
Which brings us to another problem - class_name already does too much: https://github.com/godotengine/godot-proposals/issues/1047. Adding even more functionality to it sounds like a bad idea.
And before someone misunderstands - i support the idea of giving access to the information OP is asking for. I support it so much i want it available to all our classes (files), not just those with class_name. Therefore i don't want this information being held hostage by the class_name.

please, at least update documentation, I'm using 3.2.2 and still I had to find this thread to understand how it works

For beginners:
If you want to export var script: GDScript and get_class() without having to create an instance, use static function:
extends ClassName

static static_get_class():
    return "ClassName"

func get_class():
    return static_get_class()

func _to_string():
    return "[%s: %s]" % [static_get_class(), name]

and just script.static_get_class()

the code editor will also freak if you try to pass any built in type as an static Reference argument, which is certainly a bug. during runtime itll work no problem but the compiler will only let you pass a built in type into a static GDScriptNativeClass argument
i really hope that these issues are fixed, because working with custom types is super difficult, and its been plaguing the engine for quite some time, which is odd being that godot is object oriented
get_class override works but comparing strings aint got nothin on comparing actual types

What about adding get_extended_class() is_extended_class()  (or similar) which can work on class_name as well as any class in the extension chain.

This is expected, those methods get the name of the native class

Would it not make more sense to a methode get_native_class() to return the native class name and that get_class() method of returning the name of the instance class?

This is expected, those methods get the name of the native class. It never worked with inner classes, which also have names.
Also, it's not clear what would this return if the script class don't have a name.

By the docs, and in my testing, is_class() returns true for all objects that inherit from the argument class, so for instance is_class("Node") returns true for a Spatial or anything else that inherits from Node. That means changing is_class() to support custom classes would not break any existing code that isn't broken already. If anything, maybe there is a case for adding a strict version that does not recognize child classes as their parents.
For get_class(), I don't see the use case of its current behaviour at all. In all situations I can think of, returning the latest native parent instead of the actual class is a hindrance to be worked around rather than desirable.

@Poldovico

For get_class(), I don't see the use case of its current behaviour at all. In all situations I can think of, returning the latest native parent instead of the actual class is a hindrance to be worked around rather than desirable.

This is frequently the desired behavior in low-level engine code where you are searching for the name of the current object that you would like to pass to some other context which will in turn use that name to look up the class in the ClassDB. The get_class() method originates within the /core layer of the engine where this type of use was and still is prevalent long before globally named script types were even a thing.
The current master branch's get_class_name() method appears to satisfy the desired use case since it directly returns the most-derived name available for the current object. There does not yet appear to be a corresponding method for testing inheritance on the Object class.
Mentioning godotengine/godot-proposals#5444 for loose relevance as it could potentially supply a standardized means of performing such queries.

I think get_class() like @willnationsdev  says should return current class and get_base_class() should return base class. I think that's how is done in most languages.

This is frequently the desired behavior in low-level engine code

Though that would not be in GDScript, correct?
I can see how this came about by simply exposing the underlying engine method, but surely for use in GDScript the behaviour requested here would make more sense?

@filipworksdev

I think get_class() like @willnationsdev says...and get_base_class() should return...class. So by extension get_class_name()...and get_base_class_name() should return...class name.

That's not quite what I said. It isn't about having some method(s) to return a class/reflection object and other methods to return just names. I merely stated that get_class() does return only the current ClassDB-registered object's name and that it does this for good reason as it is highly relevant to executing "high-performance" reflection operations (relatively speaking) within /core.
The ClassDB type's ClassInfo struct is not exposed to the scripting API, so get_class() and all the others cannot return actual reflection / type info objects. After re-examining the source code, it seems like get_class() and get_class_name() both only return the name of the ClassDB-registered type (including GDExtension types in 4.0), but one returns String and the other StringName. That's the only difference (makes more sense to me now).
If my above-mentioned proposal were implemented and you added a TypeHandle class of some sort to the scripting API, my suggestion was NOT that we could make get_class() return said object. It was an assertion that having that object exist could solve the use case of querying for the correct name on any given object. For example...
var obj = some_method()
# Options for how to get the name...
var n1 = TypeHandle.new(obj).name # verbose w/ TypeHandle as Resource. Expensive, but easy to implement.
var n2 = TypeHandle(obj).name # verbose w/ TypeHandle as built-in. Inexpensive, but MUCH harder to implement.
var n3 = get_type(obj).name # concise, w/ GDScript adding a get_type global function.
var n4 = typeof(obj).name # concise, compatibility-breaking, would replace existing global function.

The problem with putting it into /core is that, architecturally, it is wholly unnecessary to any of the /core logic, so including it would not only bloat /core but also introduce performance issues. The proposal was suggested to solve the very specific use case of resolving type ambiguities between Godot's various type representations. Thus the object in question would have a built-in performance penalty of needing to check various things about the object before it can make any determination of what to return from its methods (converting a constant-time operation to a linear-time operation where N is each type representation that the engine uses).
@Poldovico

Though that would not be in GDScript, correct?
I can see how this came about by simply exposing the underlying engine method, but surely for use in GDScript the behaviour requested here would make more sense?

You're not wrong. Having GDScript provide a more intuitive behavior for this method's return value would be a much better UX for Godot's users. However, in order to implement it, there are various issues at play (idk how familiar you are with the codebase, so I'm going to explain for the perspective of someone who only knows the scripting API, in case other Godot users read this).
In order to make the method do that, you'd have to support it in one of the following ways:

Modify the C++ GDCLASS macro for Object-derived types so that the virtual get_class() method additionally checks the current object instance for a ScriptInstance and forward the operation to that if it exists.
Modify the GDScriptInstance class to override the get_class() method and provide the expected behavior.

Option 1 would result in all of the primary use cases of get_class() in /core suddenly experiencing a severe performance loss due to the need to perform additional checks where previously they directly queried the class hierarchy and got a result. It damages the quality and health of the engine's codebase and is therefore not a good solution for this problem.
Option 2 is the direct and intuitive solution that takes place at a more convenient architectural layer, but while it sounds simple on the surface, it has an insidious cost as a side effect.
The expected implementation you might have in your mind is that all we need to do is overload some get_class() method somewhere in the GDScript language's module, right? Well, GDScriptInstance is the class responsible for accessing the scripting API on Object instances with a GDScript attached to them. However, GDScriptInstance itself extends ScriptInstance which is not an Object and thus is not exposed to the scripting API. As such, in order to access "instance" information through the GDScript language, it relies on the dynamic calls of the script bindings. That is, in order to call any method on the instance, you (more or less) call the generic call() method and pass in "get_class" as the name of the method you want to call. There is no virtual C++ function you can simply override to make GDScript specialize its logic for that one method.
Instead, to have specialized behavior for a single function, you have to do performance-intensive hacks like this. You force every method call to check for whether that special-case method is being called or not and branch the logic accordingly. Consequently, the mere existence of the specialized logic slows down the time required to execute every other method call. And the more special cases you add, the bigger the performance hit becomes. They already do it for _ready() because that's crucial to delivering a good user experience with the Node API, but doing so for get_class() would be a prohibitively high cost just to accommodate a slightly better UX.
I hope this helps to clarify the difficulty of delivering a proper solution. Any solution that overrides or injects the logic at the ideal architectural layer introduces a significant cost to all scripting while any solution that modifies the /core unnecessarily damages performance and introduces bloat since /core doesn't need it.
The only solution that I could see maybe being approved would be something that introduces only the barest minimum of bloat to /core without negatively impacting any aspect of performance at that architectural layer. For example...

Make the following changes in core...

Modify the C++ GDCLASS macro for Object-derived types so that get_class() is renamed to get_core_class().

As a result, we would need to refactor the entire engine's use of get_class() to use get_core_class() instead, including the GDNative API (which therefore impacts all GDExtension code and is therefore compatibility-breaking).

NOT in the GDCLASS macro, re-add get_class as a non-virtual method. /core would likely never use this method but it might find usage in upper architectural layers (and definitely would at the scripting layer). The updated implementation would specifically check to see if the object has a Script attached to it and then proceed to iteratively check its script inheritance hierarchy for the first match in the ScriptServer global script classes to return its name. If no match is found, then it would defer to calling the get_core_class() method.
Update the Object::_bind_methods() implementation to reflect all of the above changes (so both get_class() and get_core_class() are exposed to the scripting API).
Repeat the above steps for get_class_name() -> get_core_class_name() which is new to Godot 4.

This would result in things inside the engine changing significantly (using different methods now), but would shift the scripting API exposed to the public to have much more intuitive behavior. It would also require repo maintainers to verify that all unmerged PRs are re-evaluated to ensure that their usage of get_class() is likewise updated to get_core_class() to ensure no new code added post-refactoring re-introduces legacy behavior expectations into the codebase. Perhaps there's a scripted operation that could do that and generate comments on the PRs that involve code changes using get_class()?

It doesn't look like you can override get_class() in godot 4.0. I've attached an example project, just run main.tscn
class_name CustomClass
extends Node3D

func get_class() -> String:
	return "CustomClass"

func _ready() -> void:
	print(get_class())

godot-override-get-class.zip

The 3.5 class_name behavior just gave me a headache in a project I'm working on.
I have a set of "SpawnSpot" nodes and a "SummonBrain" node for a game that spawns enemies on a timer; the SummonBrain tracks the timer and some other persistent info (what level enemies should be, etc) and the SpawnSpots handle the logic for deciding where to place an enemy (checking that the target location is empty, etc). Initially, I had SpawnSpots look for the SummonBrain by absolute path, but I wanted to make this more robust--I don't like the idea of having to place the SummonBrain in the right place in the scene tree, with the right name, every time. It would be better if I could find it by classname, to avoid future problems if I want to rename the SummonBrain or create a new type extending from it.
So I grabbed a snippet for finding a node by class...but it didn't work. It reported a Node2D instead of the class_name I had set. What gives? I can create a node of class SummonBrain in the editor, right? In fact, that's exactly what I did to add the SummonBrain to my testing scene! Surely it's a node of class SummonBrain, since the editor says it's a node of class SummonBrain:

The expected behavior is that when I create a node of class X, and the editor UI says it's of class X, because I have class_name X in the script that defines it, X.get_class() returns "X". A node of class X is a node of class X. I don't see why you'd expect otherwise--I don't expect float.get_type() to return anything other than "float". I don't expect Node2D.get_class() to return "Node". This behavior feels like a holdover from before class_name was added to GDScript.

It doesn't look like you can override get_class() in godot 4.0. I've attached an example project, just run main.tscn
class_name CustomClass
extends Node3D

func get_class() -> String:
	return "CustomClass"

func _ready() -> void:
	print(get_class())

godot-override-get-class.zip

Overriding (shadowing) core functions in Godot4 are not allowed, I had to learn that painfully.
It works only when you call the shadowed function over the custom type, and will be never work when the engine itself is calling.
You can test it by
var node : CustomClass = CustomClass.new()
prints(node.get_class()) # prints "CustomClass"

# assign to the base class
var node : Node3D = CustomClass.new()
prints(node.get_class()) # prints "Node3D"

Hi ! From your descriptive example, it looks like get_class gives in fact the referencing var class name, not the referenced objet class name. If this an exact fact, I think a new get_objet_class() method would be more suitable to get referenced object class. Moreover if - my deduced -  behaviour of get_class is maintained (and I would rename get_class() to be get_var_class() in order to be more explicit about its actual purpose and  clarify methods behaviours in users head). Otherwise do not mind it, just forget what I have written here.

Recently happened upon this when wanting to create a list from a custom class type "StatusEffect" with child scripts such as "BurnStatus" and "PoisonStatus".
It now requires that I set up some sort of enum or resource_name to compare the different children or need to do a long list of If statements to manually check: If status is BurnStatus and other_status is BurnStatus.
overriding get_class() now also pushes an error, so that is not an option.
having access to the custom class_name when calling get_class() would be extremely appreciated behaviour and is also what one would expect it to do at first glance.

Recently happened upon this when wanting to create a list from a custom class type "StatusEffect" with child scripts such as "BurnStatus" and "PoisonStatus".
It now requires that I set up some sort of enum or resource_name to compare the different children or need to do a long list of If statements to manually check: If status is BurnStatus and other_status is BurnStatus.
overriding get_class() now also pushes an error, so that is not an option.
having access to the custom class_name when calling get_class() would be extremely appreciated behaviour and is also what one would expect it to do at first glance.

For the time being I add get_class_name() as a custom function down the inheritance tree returning a string that I put in manually. But definitely looking forward to 4.1.

Recently happened upon this when wanting to create a list from a custom class type "StatusEffect" with child scripts such as "BurnStatus" and "PoisonStatus".
It now requires that I set up some sort of enum or resource_name to compare the different children or need to do a long list of If statements to manually check: If status is BurnStatus and other_status is BurnStatus.
overriding get_class() now also pushes an error, so that is not an option.
having access to the custom class_name when calling get_class() would be extremely appreciated behaviour and is also what one would expect it to do at first glance.

For the time being I add get_class_name() as a custom function down the inheritance tree returning a string that I put in manually. But definitely looking forward to 4.1.

In my case I am using Resources, so then I can make use of resource_names and pushing a warning when a name is not present, but yeah 4.1 is gonna be awesome

overriding get_class() now also pushes an error, so that is not an option.

Actually, the error can be turned into a warning or even muted in the project settings.

Would it be possible to create a method called get_script_class and is_script_class and leave anything else as is?

Someone mentioned in #62273 that Script::get_global_name() needs to be exposed to gdscript and that it'd resolve this problem. What exactly does Script::get_global_name() do? Is it just a cleaner, standardized way to get the classname when a custom class is present?

This is a great time to change behavior, the more versions change, the heavier the compatibility baggage will be, and I hope this issue will be resolved soon!

I don't think changing get_class() behavior is a good idea. Yes, we should unify the three-level type system we have, but in a different way. For example, with a class that represents a type, see the discussion:

godotengine/godot-proposals#6502

I have a GDType class prototype (written in GDScript). I hope to finish it soon and post it to test the idea.

On my opinion, first, I agree with the suggestions here and second I want to add my experience:
I had the get_class() function shadowed, on Godot 3.x. Now, trying to go to Godot 4 I decided to de-shadow all. And for my surprise, all things broke because I depend too much on get_class() on my code just to determine what kind of Item is it. And everything returns "Node2D"!! LoL. And the player character too returns "KinematicBody2D", so my player is of class "KinematicBody2D". xD I don't know from what realm is that character but I think he is from the town of the computer science xD
Well, now I have to use something like "item is Weapon". Leaving me sometimes lead to recursive references that ends in an error on the Godot Editor. So that is not always possible.
I wanted to share my experience to make it more important to take in account. Because I really depends on knowing the class_name. And as I read above I am not the only one.
I don't know for what Godot use get_class() internally but I think it is important for the right functioning of the engine. At least can we have some other function to return a String of the class_name of our own scripts? I hope yes.
Now for my characters I decided to create a redundant function just to define the same as class_name but returning a String. And for items I need to save that to a file so I really don't know how I will do for now. Because I need to save the class_name to a file so I can load the same item class. LoL, that really broke my game!

Would be great for tools too, it's not just the get_call function but also to have it in class_name field of the get_property_list(). Would be so much convenient to define it and make some UI by types.

According to my understanding, the demand for this feature often stems from "type recognition." We need some built-in and convenient way to distinguish different types and then... call their functions. I suddenly realized that this is actually an "interface" issue. GDScript does not have true interfaces, and it is foreseeable that it will not introduce interfaces like C++ or C#. However, I think there is a design that can be borrowed, which is the interface of the GO language. Some people may not be familiar with GO, so I can briefly introduce it: Simply put, if you want to implement an interface, you don't need to inherit it in any way, but simply implement the methods it requires:
// An interface
type Duck interface {
  public function gagaga();
  public function fly();
}

// No need to inherit
type MagicDuck struct{

}

func (d Duck) gagaga(){
	//xxxxxxxxxxxxxxx
}

func (d Duck) fly(){
	//xxxxxxxxxxxxxxx
}

MagicDuck does not need to inherit any interface. It implements all the required methods of Duck, so some_duck: Duck = MagicDuck() is valid, that is the logic of go.
Perhaps GDScript can draw inspiration from this method to solve the interface problem.

According to my understanding, the demand for this feature often stems from "type recognition." We need some built-in and convenient way to distinguish different types and then... call their functions. I suddenly realized that this is actually an "interface" issue. GDScript does not have true interfaces, and it is foreseeable that it will not introduce interfaces like C++ or C#. However, I think there is a design that can be borrowed, which is the interface of the GO language. Some people may not be familiar with GO, so I can briefly introduce it: Simply put, if you want to implement an interface, you don't need to inherit it in any way, but simply implement the methods it requires:
// An interface
type Duck interface {
  public function gagaga();
  public function fly();
}

// No need to inherit
type MagicDuck struct{

}

func (d Duck) gagaga(){
	//xxxxxxxxxxxxxxx
}

func (d Duck) fly(){
	//xxxxxxxxxxxxxxx
}

MagicDuck does not need to inherit any interface. It implements all the required methods of Duck, so some_duck: Duck = MagicDuck() is valid, that is the logic of go.
Perhaps GDScript can draw inspiration from this method to solve the interface problem.

You don't need to make func (d MagicDuck) fly { ... } ?
But yeah make me think there is a has_method() on the Object that allow basic checks, there is even meta_data system but I think it's kind of redundant and not straightforward when defining a class_name.
And defining them in each class of your project... It is not scaling.

sure it will be func (d MagicDuck) Fly { ... }  , I made some mistake :)

If you're ever wondering why almost all Godot tools and plugins written in GDScript stay exactly only one level of abstraction above the Editor (i.e. they remain desperately self-contained, without ever being built on top of other plugins, or without ever being designed as base under other plugins), this is it. Look no further.
By "it", I mean the impossibility of ever knowing exactly where you stand (what classes exist, what are their names, in what class am I, etc.).
Meanwhile, the C# code base becomes more robust every day, creating an ever-growing drift between "serious" Godot (C#) and "small teams/small projects" Godot (GDScript).

Can anyone explain why we can't just make a new method that returns the custom class_name of an object?

Can anyone explain why we can't just make a new method that returns the custom class_name of an object?

The global name is exposed in https://github.com/godotengine/godot/pull/80487 since 4.3.

Wait, so does this mean we can reference a custom class_name in 4.3.beta? Is that the same as global name?

Can anyone explain why we can't just make a new method that returns the custom class_name of an object?

The global name is exposed in #80487 since 4.3.beta.

That seems to work, but not when using inner classes 🤔

I was trying to find a way to to use is but it doesn't accept passed vars, similar to what this person was doing.
A workaround I found was to use var names and the in operator to check. So with every class_name declaration, I also declare a var with it.
# Mover.gd
extends Character
class_name Mover
var class_mover

# Character.gd
extends Node2D
class_name Character
var class_character

is_object_inherit_from_class(obj, class_str):
    var _class_name = "class_%s" % class_str.to_lower()
    if _class_name in obj:
        return true
    return false

in operator will traverse down what is being extended.
We could potentially add one parameter to is_class to extend down to derived classes as well. I find it indispensable.

@faulknermano See is_instance_of.

@faulknermano See is_instance_of.

Hi @kleonc , thanks, I've not seen that before.
However, this doesn't seem to work in my implementation quite in the same way. To recap: my aim is to use a static function to determine if a given object is derived from a particular class. When I pass a type to this function, it doesn't seem come out the way I expect it.
I've rewritten my func to use is_instance_of and it looks like:
static func get_parent_of_class_type(object: Node, class_type):
    """ Get first parent with attached script. Will keep on iterating up the hierarchy until it one. First one that matches is returned. If not, then returns null """
    var parent = object.get_parent()
    while parent != null:
        print("object: ", str(object))
        print("class_type: ", str(class_type))
        print("is_instance_of(object, class_type): ", str(is_instance_of(object, class_type)))
        if is_instance_of(object, class_type):
            return parent
        # if parent == class_id:
        #     return parent

        parent = parent.get_parent()
        if parent == null:
            return

In the output I see something like:
character: PlayerCombatCharacter:<Node#60314092950>
class_type: <GDScript#-9223372009289808666>
is_instance_of(object, class_type): false

My call is like this:
var __character
var character:
    get:
        if __character == null:
            # __character = Statics.get_parent_of_class(self, "Character")
            __character = Statics.get_parent_of_class_type(self, Character)
        return __character
    set(value): pass

I.e.
__character = Statics.get_parent_of_class_type(self, Character)

.. where PlayerCombatCharacter extends from Character.
Am I supposed to transform the class type GDScript into something that I can use to compare?

https://github.com/godotengine/godot-proposals/issues/7474


arch: avr: Author Gregory Nutt: update licenses to Apache

Summary
Gregory Nutt has submitted the SGA and we can migrate the licenses to Apache.
Impact
NONE
Testing
NONE

please ignore the Include warnings


NetCDF: Filter error: undefined filter encountered

# Platform specification
Architecture: aarch64
NetCDF C Library: 4.9.2, but the same problem is raised even for 4.9.0
Operating System: Linux CentOS 9 Stream - Linux localhost.localdomain 5.14.0-340.el9.aarch64 #1 SMP PREEMPT_DYNAMIC Mon Jul 17 12:31:16 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux
gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/aarch64-redhat-linux/11/lto-wrapper
Target: aarch64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-host-pie --enable-host-bind-now --enable-languages=c,c++,fortran,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --enable-plugin --enable-initfini-array --without-isl --enable-multilib --with-linker-hash-style=gnu --enable-gnu-indirect-function --build=aarch64-redhat-linux --with-build-config=bootstrap-lto --enable-link-serialization=1
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.4.1 20230605 (Red Hat 11.4.1-2) (GCC)
mpicc -v
mpicc for MPICH version 4.1.1
Using built-in specs.
Reading specs from /usr/lib/rpm/redhat/redhat-hardened-cc1
Reading specs from /usr/lib/rpm/redhat/redhat-annobin-cc1
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/aarch64-redhat-linux/11/lto-wrapper
Target: aarch64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-host-pie --enable-host-bind-now --enable-languages=c,c++,fortran,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --enable-plugin --enable-initfini-array --without-isl --enable-multilib --with-linker-hash-style=gnu --enable-gnu-indirect-function --build=aarch64-redhat-linux --with-build-config=bootstrap-lto --enable-link-serialization=1
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.4.1 20230605 (Red Hat 11.4.1-2) (GCC)
mpicxx -v
mpicxx for MPICH version 4.1.1
Using built-in specs.
Reading specs from /usr/lib/rpm/redhat/redhat-hardened-cc1
Reading specs from /usr/lib/rpm/redhat/redhat-annobin-cc1
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/aarch64-redhat-linux/11/lto-wrapper
Target: aarch64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-host-pie --enable-host-bind-now --enable-languages=c,c++,fortran,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --enable-plugin --enable-initfini-array --without-isl --enable-multilib --with-linker-hash-style=gnu --enable-gnu-indirect-function --build=aarch64-redhat-linux --with-build-config=bootstrap-lto --enable-link-serialization=1
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.4.1 20230605 (Red Hat 11.4.1-2) (GCC)
The steps performed to install and to access a Zarr dataset via the library are listed below.
# Download and install s3 library
git clone https://github.com/aws/aws-sdk-cpp.git
cd aws-sdk-cpp
git submodule update --init --recursive
srcdir=$(pwd)
mkdir build
cd build
cmake $srcdir -DBUILD_ONLY=s3 -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=/path/to/aws-sdk-cpp
make -j2 -k
make install
# Download and install NetCDF library
wget https://downloads.unidata.ucar.edu/netcdf-c/4.9.2/netcdf-c-4.9.2.zip
unzip netcdf-c-4.9.2.zip
cd netcdf-c-4.9.2
./configure --prefix=/path/to/netcdf-4.9.2 --enable-s3 LDFLAGS="-L/path/to/aws-sdk-cpp/lib64 -laws-cpp-sdk-s3" CPPFLAGS=-I/path/to/aws-sdk-cpp/include CC=mpicc CPP=mpicxx
make -j2 -k
make install
# Download the input Zarr data
cd /data/zarr
wget -r -H -N --cut-dirs=4 --include-directories="/v1/" "https://swiftbrowser.dkrz.de/public/dkrz_0b2a0dcc-1430-4a8a-9f25-a6cb8924d92b/CMCC_CMIP/CMIP6.CMIP.CMCC.CMCC-CM2-HR4.historical.r1i1p1f1.day.pr.gn.v20200904/?show_all"
The tests are listed below:
# Tests
export LD_LIBRARY_PATH=/path/to/netcdf-4.9.2/lib:/path/to/aws-sdk-cpp/lib64:$LD_LIBRARY_PATH
## Test 1: passed
/path/to/netcdf-4.9.2/bin/ncdump -h s3://storage.googleapis.com/cmip6/CMIP6/HighResMIP/CMCC/CMCC-CM2-HR4/highresSST-present/r1i1p1f1/Amon/rsds/gn/v20170706/#mode=zarr
netcdf #mode=zarr {
dimensions:
lat = 192 ;
bnds = 2 ;
lon = 288 ;
time = 804 ;
variables:
double lat(lat) ;
lat:axis = "Y" ;
lat:bounds = "lat_bnds" ;
lat:long_name = "latitude" ;
lat:standard_name = "latitude" ;
lat:units = "degrees_north" ;
double lat_bnds(lat, bnds) ;
double lon(lon) ;
lon:axis = "X" ;
lon:bounds = "lon_bnds" ;
lon:long_name = "longitude" ;
lon:standard_name = "longitude" ;
lon:units = "degrees_east" ;
double lon_bnds(lon, bnds) ;
float rsds(time, lat, lon) ;
rsds:cell_measures = "area: areacella" ;
rsds:cell_methods = "area: time: mean" ;
rsds:comment = "surface solar irradiance for UV calculations" ;
rsds:history = "2017-07-02T15:44:13Z altered by CMOR: Converted units from ' W m-2' to 'W m-2'." ;
rsds:long_name = "Surface Downwelling Shortwave Radiation" ;
rsds:original_units = "W m-2" ;
rsds:standard_name = "surface_downwelling_shortwave_flux_in_air" ;
rsds:units = "W m-2" ;
int64 time(time) ;
time:axis = "T" ;
time:bounds = "time_bnds" ;
time:calendar = "noleap" ;
time:long_name = "time" ;
time:standard_name = "time" ;
time:units = "hours since 1948-01-16 12:00:00.000000" ;
double time_bnds(time, bnds) ;
time_bnds:calendar = "365_day" ;
time_bnds:units = "days since 1948-01-01" ;
// global attributes:
:CDI = "Climate Data Interface version 1.8.0 (http://mpimet.mpg.de/cdi)" ;
:CDO = "Climate Data Operators version 1.8.0 (http://mpimet.mpg.de/cdo)" ;
:Conventions = "CF-1.7 CMIP-6.0" ;
:activity_id = "HighResMIP" ;
:cmor_version = "3.2.3" ;
:coordinates = "lon_bnds time_bnds lat_bnds" ;
:creation_date = "2017-07-02T15:44:13Z" ;
:data_specs_version = "01.00.23" ;
:end_year = "2014" ;
:experiment = "forced atmosphere experiment for 1950-2014" ;
:experiment_id = "highresSST-present" ;
:external_variables = "areacella" ;
:forcing_index = 1 ;
:frequency = "mon" ;
:further_info_url = "https://furtherinfo.es-doc.org/CMIP6.CMCC.CMCC-CM2-HR4.highresSST-present.none.r1i1p1f1" ;
:grid = "native atmosphere regular grid (192x288 latxlon)" ;
:grid_label = "gn" ;
:history = "2017-07-02T15:44:13Z CMOR rewrote data to be consistent with CF standards and CMIP6 requirements.; 2019-04-23T15:50:59Z DataSpecsVersionAdd, FurtherInfoUrlToHttps" ;
:initialization_index = 1 ;
:institution = "Fondazione Centro Euro-Mediterraneo sui Cambiamenti Climatici, Lecce 73100, Italy" ;
:institution_id = "CMCC" ;
:license = "CMIP6 model data produced by CMCC is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License (https://creativecommons.org/licenses). Consult https://pcmdi.llnl.gov/CMIP6/TermsOfUse for terms of use governing CMIP6 output, including citation requirements and proper acknowledgment. Further information about this data, including some limitations, can be found via the further_info_url (recorded as a global attribute in this file). The data producers and data providers make no warranty, either express or implied, including, but not limited to, warranties of merchantability and fitness for a particular purpose. All liabilities arising from the supply of the information (including any liability arising in negligence) are excluded to the fullest extent permitted by law." ;
:min_number_yrs_per_sim = "65" ;
:mip_era = "CMIP6" ;
:nominal_resolution = "1x1 degree" ;
:parent_activity_id = "no parent" ;
:parent_experiment_id = "no parent" ;
:parent_mip_era = "no parent" ;
:physics_index = 1 ;
:product = "model-output" ;
:realization_index = 1 ;
:realm = "atmos" ;
:source = "CMCC-CM2-HR4 (2016): aerosol: prescribed MACv2-SP atmos: CAM4 (1deg; 288 x 192 longitude/latitude; 26 levels; top at ~2 hPa) atmosChem: none land: CLM4.5 (SP mode) landIce: none ocean: NEMO3.6 (ORCA0.25 1/4 deg from the Equator degrading at the poles; 1442 x 1051 longitude/latitude; 50 vertical levels; top grid cell 0-1 m) ocnBgchem: none seaIce: CICE4.0" ;
:source_id = "CMCC-CM2-HR4" ;
:source_type = "AGCM" ;
:start_year = "1950" ;
:sub_experiment = "none" ;
:sub_experiment_id = "none" ;
:table_id = "Amon" ;
:table_info = "Creation Date:(22 April 2017) MD5:d3f61e4124f67845cd50ff647ba0c673" ;
:tier = "1" ;
:title = "CMCC-CM2-HR4 model output prepared for CMIP6" ;
:tracking_id = "hdl:21.14100/6bc46076-c6c8-4f5b-acf0-d79baab75d7e" ;
:variable_id = "rsds" ;
:variant_label = "r1i1p1f1" ;
:status = "2019-11-16;created;by<EMAIL_ADDRESS>;
}
## Test 2: failed
/path/to/netcdf-4.9.2/bin/ncdump -hs s3://storage.googleapis.com/cmip6/CMIP6/HighResMIP/CMCC/CMCC-CM2-HR4/highresSST-present/r1i1p1f1/Amon/rsds/gn/v20170706/#mode=zarr
netcdf #mode=zarr {
dimensions:
lat = 192 ;
bnds = 2 ;
lon = 288 ;
time = 804 ;
variables:
double lat(lat) ;
lat:axis = "Y" ;
lat:bounds = "lat_bnds" ;
lat:long_name = "latitude" ;
lat:standard_name = "latitude" ;
lat:units = "degrees_north" ;
lat:_Storage = "chunked" ;
lat:_ChunkSizes = 192 ;
NetCDF: Filter error: undefined filter encountered
Location: file ncdump.c; fcn pr_att_specials line 1060
## Test 3: failed
/path/to/netcdf-4.9.2/bin/ncdump -v lat s3://storage.googleapis.com/cmip6/CMIP6/HighResMIP/CMCC/CMCC-CM2-HR4/highresSST-present/r1i1p1f1/Amon/rsds/gn/v20170706/#mode=zarr
netcdf #mode=zarr {
dimensions:
lat = 192 ;
bnds = 2 ;
lon = 288 ;
time = 804 ;
variables:
double lat(lat) ;
lat:axis = "Y" ;
lat:bounds = "lat_bnds" ;
lat:long_name = "latitude" ;
lat:standard_name = "latitude" ;
lat:units = "degrees_north" ;
double lat_bnds(lat, bnds) ;
double lon(lon) ;
lon:axis = "X" ;
lon:bounds = "lon_bnds" ;
lon:long_name = "longitude" ;
lon:standard_name = "longitude" ;
lon:units = "degrees_east" ;
double lon_bnds(lon, bnds) ;
float rsds(time, lat, lon) ;
rsds:cell_measures = "area: areacella" ;
rsds:cell_methods = "area: time: mean" ;
rsds:comment = "surface solar irradiance for UV calculations" ;
rsds:history = "2017-07-02T15:44:13Z altered by CMOR: Converted units from ' W m-2' to 'W m-2'." ;
rsds:long_name = "Surface Downwelling Shortwave Radiation" ;
rsds:original_units = "W m-2" ;
rsds:standard_name = "surface_downwelling_shortwave_flux_in_air" ;
rsds:units = "W m-2" ;
int64 time(time) ;
time:axis = "T" ;
time:bounds = "time_bnds" ;
time:calendar = "noleap" ;
time:long_name = "time" ;
time:standard_name = "time" ;
time:units = "hours since 1948-01-16 12:00:00.000000" ;
double time_bnds(time, bnds) ;
time_bnds:calendar = "365_day" ;
time_bnds:units = "days since 1948-01-01" ;
// global attributes:
:CDI = "Climate Data Interface version 1.8.0 (http://mpimet.mpg.de/cdi)" ;
:CDO = "Climate Data Operators version 1.8.0 (http://mpimet.mpg.de/cdo)" ;
:Conventions = "CF-1.7 CMIP-6.0" ;
:activity_id = "HighResMIP" ;
:cmor_version = "3.2.3" ;
:coordinates = "lon_bnds time_bnds lat_bnds" ;
:creation_date = "2017-07-02T15:44:13Z" ;
:data_specs_version = "01.00.23" ;
:end_year = "2014" ;
:experiment = "forced atmosphere experiment for 1950-2014" ;
:experiment_id = "highresSST-present" ;
:external_variables = "areacella" ;
:forcing_index = 1 ;
:frequency = "mon" ;
:further_info_url = "https://furtherinfo.es-doc.org/CMIP6.CMCC.CMCC-CM2-HR4.highresSST-present.none.r1i1p1f1" ;
:grid = "native atmosphere regular grid (192x288 latxlon)" ;
:grid_label = "gn" ;
:history = "2017-07-02T15:44:13Z CMOR rewrote data to be consistent with CF standards and CMIP6 requirements.; 2019-04-23T15:50:59Z DataSpecsVersionAdd, FurtherInfoUrlToHttps" ;
:initialization_index = 1 ;
:institution = "Fondazione Centro Euro-Mediterraneo sui Cambiamenti Climatici, Lecce 73100, Italy" ;
:institution_id = "CMCC" ;
:license = "CMIP6 model data produced by CMCC is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License (https://creativecommons.org/licenses). Consult https://pcmdi.llnl.gov/CMIP6/TermsOfUse for terms of use governing CMIP6 output, including citation requirements and proper acknowledgment. Further information about this data, including some limitations, can be found via the further_info_url (recorded as a global attribute in this file). The data producers and data providers make no warranty, either express or implied, including, but not limited to, warranties of merchantability and fitness for a particular purpose. All liabilities arising from the supply of the information (including any liability arising in negligence) are excluded to the fullest extent permitted by law." ;
:min_number_yrs_per_sim = "65" ;
:mip_era = "CMIP6" ;
:nominal_resolution = "1x1 degree" ;
:parent_activity_id = "no parent" ;
:parent_experiment_id = "no parent" ;
:parent_mip_era = "no parent" ;
:physics_index = 1 ;
:product = "model-output" ;
:realization_index = 1 ;
:realm = "atmos" ;
:source = "CMCC-CM2-HR4 (2016): aerosol: prescribed MACv2-SP atmos: CAM4 (1deg; 288 x 192 longitude/latitude; 26 levels; top at ~2 hPa) atmosChem: none land: CLM4.5 (SP mode) landIce: none ocean: NEMO3.6 (ORCA0.25 1/4 deg from the Equator degrading at the poles; 1442 x 1051 longitude/latitude; 50 vertical levels; top grid cell 0-1 m) ocnBgchem: none seaIce: CICE4.0" ;
:source_id = "CMCC-CM2-HR4" ;
:source_type = "AGCM" ;
:start_year = "1950" ;
:sub_experiment = "none" ;
:sub_experiment_id = "none" ;
:table_id = "Amon" ;
:table_info = "Creation Date:(22 April 2017) MD5:d3f61e4124f67845cd50ff647ba0c673" ;
:tier = "1" ;
:title = "CMCC-CM2-HR4 model output prepared for CMIP6" ;
:tracking_id = "hdl:21.14100/6bc46076-c6c8-4f5b-acf0-d79baab75d7e" ;
:variable_id = "rsds" ;
:variant_label = "r1i1p1f1" ;
:status = "2019-11-16;created;by<EMAIL_ADDRESS>;
data:
NetCDF: Filter error: undefined filter encountered
Location: file vardata.c; fcn print_rows line 478
## Test 4: passed
/path/to/netcdf-4.9.2/bin/ncdump -h file:///data/zarr/swift.dkrz.de#mode=zarr
netcdf swift.dkrz {
dimensions:
lat = 192 ;
bnds = 2 ;
lon = 288 ;
time = 60225 ;
variables:
double lat(lat) ;
lat:axis = "Y" ;
lat:bounds = "lat_bnds" ;
lat:long_name = "Latitude" ;
lat:standard_name = "latitude" ;
lat:units = "degrees_north" ;
double lat_bnds(lat, bnds) ;
double lon(lon) ;
lon:axis = "X" ;
lon:bounds = "lon_bnds" ;
lon:long_name = "Longitude" ;
lon:standard_name = "longitude" ;
lon:units = "degrees_east" ;
double lon_bnds(lon, bnds) ;
float pr(time, lat, lon) ;
pr:cell_measures = "area: areacella" ;
pr:cell_methods = "area: time: mean" ;
pr:comment = "includes both liquid and solid phases" ;
pr:long_name = "Precipitation" ;
pr:missing_value = 1.00000002004088e+20 ;
pr:original_name = "PRECT" ;
pr:standard_name = "precipitation_flux" ;
pr:units = "kg m-2 s-1" ;
int64 time(time) ;
time:axis = "T" ;
time:bounds = "time_bnds" ;
time:calendar = "noleap" ;
time:long_name = "time" ;
time:standard_name = "time" ;
time:units = "days since 1850-01-01 12:00:00.000000" ;
double time_bnds(time, bnds) ;
time_bnds:calendar = "365_day" ;
time_bnds:units = "days since 1850-01-01" ;
// global attributes:
:Conventions = "CF-1.7 CMIP-6.2" ;
:activity_id = "CMIP" ;
:branch_method = "standard" ;
:branch_time_in_child = 0. ;
:branch_time_in_parent = 0. ;
:cmor_version = "3.5.0" ;
:comment = "none" ;
:contact = "T. Lovato" ;
:data_specs_version = "01.00.31" ;
:experiment = "all-forcing simulation of the recent past" ;
:experiment_id = "historical" ;
:external_variables = "areacella" ;
:forcing_index = 1 ;
:frequency = "day" ;
:further_info_url = "https://furtherinfo.es-doc.org/CMIP6.CMCC.CMCC-CM2-HR4.historical.none.r1i1p1f1" ;
:grid = "native atmosphere regular grid" ;
:grid_label = "gn" ;
:history = "Converted and written to swift cloud with tzis version 0.1" ;
:initialization_index = 1 ;
:institution = "Fondazione Centro Euro-Mediterraneo sui Cambiamenti Climatici, Lecce 73100, Italy" ;
:institution_id = "CMCC" ;
:license = "CMIP6 model data produced by CMCC is licensed under a Creative Commons Attribution ShareAlike 4.0 International License (https://creativecommons.org/licenses). Consult https://pcmdi.llnl.gov/CMIP6/TermsOfUse for terms of use governing CMIP6 output, including citation requirements and proper acknowledgment. Further information about this data, including some limitations, can be found via the further_info_url (recorded as a global attribute in this file) and at https:///pcmdi.llnl.gov/. The data producers and data providers make no warranty, either express or implied, including, but not limited to, warranties of merchantability and fitness for a particular purpose. All liabilities arising from the supply of the information (including any liability arising in negligence) are excluded to the fullest extent permitted by law." ;
:mip_era = "CMIP6" ;
:nominal_resolution = "100 km" ;
:parent_activity_id = "CMIP" ;
:parent_experiment_id = "piControl" ;
:parent_mip_era = "CMIP6" ;
:parent_source_id = "CMCC-CM2-HR4" ;
:parent_time_units = "days since 1850-01-01" ;
:parent_variant_label = "r1i1p1f1" ;
:physics_index = 1 ;
:product = "model-output" ;
:realization_index = 1 ;
:realm = "atmos" ;
:references = "none" ;
:run_variant = "1st realization" ;
:source = "CMCC-CM2-HR4 (2016): \naerosol: prescribed MACv2-SP\natmos: CAM4 (1deg; 288 x 192 longitude/latitude; 26 levels; top at ~2 hPa)\natmosChem: none\nland: CLM4.5 (SP mode)\nlandIce: none\nocean: NEMO3.6 (ORCA0.25 1/4 deg from the Equator degrading at the poles; 1442 x 1051 longitude/latitude; 50 vertical levels; top grid cell 0-1 m)\nocnBgchem: none\nseaIce: CICE4.0" ;
:source_id = "CMCC-CM2-HR4" ;
:source_type = "AOGCM" ;
:sub_experiment = "none" ;
:sub_experiment_id = "none" ;
:table_id = "day" ;
:table_info = "Creation Date:(05 February 2020) MD5:6a248fd76c55aa6d6f7b3cc6866b5faf" ;
:title = "CMCC-CM2-HR4 output prepared for CMIP6" ;
:tracking_id = "7af29565-027f-4d81-a74b-bee9a1235c0d" ;
:variable_id = "pr" ;
:variant_label = "r1i1p1f1" ;
}
## Test 5: failed
/path/to/netcdf-4.9.2/bin/ncdump -hs file:///data/zarr/swift.dkrz.de#mode=zarr
netcdf swift.dkrz {
dimensions:
lat = 192 ;
bnds = 2 ;
lon = 288 ;
time = 60225 ;
variables:
double lat(lat) ;
lat:axis = "Y" ;
lat:bounds = "lat_bnds" ;
lat:long_name = "Latitude" ;
lat:standard_name = "latitude" ;
lat:units = "degrees_north" ;
lat:_Storage = "chunked" ;
lat:_ChunkSizes = 192 ;
NetCDF: Filter error: undefined filter encountered
Location: file ncdump.c; fcn pr_att_specials line 1060
## Test 6: failed
/path/to/netcdf-4.9.2/bin/ncdump -v lat file:///data/zarr/swift.dkrz.de#mode=zarr
netcdf swift.dkrz {
dimensions:
lat = 192 ;
bnds = 2 ;
lon = 288 ;
time = 60225 ;
variables:
double lat(lat) ;
lat:axis = "Y" ;
lat:bounds = "lat_bnds" ;
lat:long_name = "Latitude" ;
lat:standard_name = "latitude" ;
lat:units = "degrees_north" ;
double lat_bnds(lat, bnds) ;
double lon(lon) ;
lon:axis = "X" ;
lon:bounds = "lon_bnds" ;
lon:long_name = "Longitude" ;
lon:standard_name = "longitude" ;
lon:units = "degrees_east" ;
double lon_bnds(lon, bnds) ;
float pr(time, lat, lon) ;
pr:cell_measures = "area: areacella" ;
pr:cell_methods = "area: time: mean" ;
pr:comment = "includes both liquid and solid phases" ;
pr:long_name = "Precipitation" ;
pr:missing_value = 1.00000002004088e+20 ;
pr:original_name = "PRECT" ;
pr:standard_name = "precipitation_flux" ;
pr:units = "kg m-2 s-1" ;
int64 time(time) ;
time:axis = "T" ;
time:bounds = "time_bnds" ;
time:calendar = "noleap" ;
time:long_name = "time" ;
time:standard_name = "time" ;
time:units = "days since 1850-01-01 12:00:00.000000" ;
double time_bnds(time, bnds) ;
time_bnds:calendar = "365_day" ;
time_bnds:units = "days since 1850-01-01" ;
// global attributes:
:Conventions = "CF-1.7 CMIP-6.2" ;
:activity_id = "CMIP" ;
:branch_method = "standard" ;
:branch_time_in_child = 0. ;
:branch_time_in_parent = 0. ;
:cmor_version = "3.5.0" ;
:comment = "none" ;
:contact = "T. Lovato" ;
:data_specs_version = "01.00.31" ;
:experiment = "all-forcing simulation of the recent past" ;
:experiment_id = "historical" ;
:external_variables = "areacella" ;
:forcing_index = 1 ;
:frequency = "day" ;
:further_info_url = "https://furtherinfo.es-doc.org/CMIP6.CMCC.CMCC-CM2-HR4.historical.none.r1i1p1f1" ;
:grid = "native atmosphere regular grid" ;
:grid_label = "gn" ;
:history = "Converted and written to swift cloud with tzis version 0.1" ;
:initialization_index = 1 ;
:institution = "Fondazione Centro Euro-Mediterraneo sui Cambiamenti Climatici, Lecce 73100, Italy" ;
:institution_id = "CMCC" ;
:license = "CMIP6 model data produced by CMCC is licensed under a Creative Commons Attribution ShareAlike 4.0 International License (https://creativecommons.org/licenses). Consult https://pcmdi.llnl.gov/CMIP6/TermsOfUse for terms of use governing CMIP6 output, including citation requirements and proper acknowledgment. Further information about this data, including some limitations, can be found via the further_info_url (recorded as a global attribute in this file) and at https:///pcmdi.llnl.gov/. The data producers and data providers make no warranty, either express or implied, including, but not limited to, warranties of merchantability and fitness for a particular purpose. All liabilities arising from the supply of the information (including any liability arising in negligence) are excluded to the fullest extent permitted by law." ;
:mip_era = "CMIP6" ;
:nominal_resolution = "100 km" ;
:parent_activity_id = "CMIP" ;
:parent_experiment_id = "piControl" ;
:parent_mip_era = "CMIP6" ;
:parent_source_id = "CMCC-CM2-HR4" ;
:parent_time_units = "days since 1850-01-01" ;
:parent_variant_label = "r1i1p1f1" ;
:physics_index = 1 ;
:product = "model-output" ;
:realization_index = 1 ;
:realm = "atmos" ;
:references = "none" ;
:run_variant = "1st realization" ;
:source = "CMCC-CM2-HR4 (2016): \naerosol: prescribed MACv2-SP\natmos: CAM4 (1deg; 288 x 192 longitude/latitude; 26 levels; top at ~2 hPa)\natmosChem: none\nland: CLM4.5 (SP mode)\nlandIce: none\nocean: NEMO3.6 (ORCA0.25 1/4 deg from the Equator degrading at the poles; 1442 x 1051 longitude/latitude; 50 vertical levels; top grid cell 0-1 m)\nocnBgchem: none\nseaIce: CICE4.0" ;
:source_id = "CMCC-CM2-HR4" ;
:source_type = "AOGCM" ;
:sub_experiment = "none" ;
:sub_experiment_id = "none" ;
:table_id = "day" ;
:table_info = "Creation Date:(05 February 2020) MD5:6a248fd76c55aa6d6f7b3cc6866b5faf" ;
:title = "CMCC-CM2-HR4 output prepared for CMIP6" ;
:tracking_id = "7af29565-027f-4d81-a74b-bee9a1235c0d" ;
:variable_id = "pr" ;
:variant_label = "r1i1p1f1" ;
data:
NetCDF: Filter error: undefined filter encountered
Location: file vardata.c; fcn print_rows line 478
lat =
I think the errors raised in tests 2, 3, 5 and 6 are due to the same cause.
Could you help me to solve this issue?

First, what configure options (or CMake options) did you use?
Second, what value did you use for HDF5_PLUGIN_PATH?

I built the library by appending the option --with-plugin-dir as follows:
./configure --prefix=/path/to/netcdf-4.9.2 --enable-s3 --with-plugin-dir=/path/to/netcdf-4.9.2/lib/plugins LDFLAGS="-L/path/to/aws-sdk-cpp/lib64 -laws-cpp-sdk-s3" CPPFLAGS=-I/path/to/aws-sdk-cpp/include CC=mpicc CPP=mpicxx
This resulted that in /path/to/netcdf-4.9.2/lib/plugins I can find the related libraries:
ls /path/to/netcdf-4.9.2/lib/plugins
lib__nch5blosc.la        lib__nch5bzip2.so.0        lib__nch5fletcher32.la        lib__nch5shuffle.so.0      lib__nch5zstd.la        lib__nczhdf5filters.so.0
lib__nch5blosc.so        lib__nch5bzip2.so.0.0.0    lib__nch5fletcher32.so        lib__nch5shuffle.so.0.0.0  lib__nch5zstd.so        lib__nczhdf5filters.so.0.0.0
lib__nch5blosc.so.0      lib__nch5deflate.la        lib__nch5fletcher32.so.0      lib__nch5szip.la           lib__nch5zstd.so.0      lib__nczstdfilters.la
lib__nch5blosc.so.0.0.0  lib__nch5deflate.so        lib__nch5fletcher32.so.0.0.0  lib__nch5szip.so           lib__nch5zstd.so.0.0.0  lib__nczstdfilters.so
lib__nch5bzip2.la        lib__nch5deflate.so.0      lib__nch5shuffle.la           lib__nch5szip.so.0         lib__nczhdf5filters.la  lib__nczstdfilters.so.0
lib__nch5bzip2.so        lib__nch5deflate.so.0.0.0  lib__nch5shuffle.so           lib__nch5szip.so.0.0.0     lib__nczhdf5filters.so  lib__nczstdfilters.so.0.0.0
Then, I set HDF5_PLUGIN_PATH to /path/to/netcdf-4.9.2/lib/plugins as follows:
export HDF5_PLUGIN_PATH=/path/to/netcdf-4.9.2/lib/plugin
and now all the tests passed.
I thank you.

I'll take a look, I'm curious if the LD_LIBRARY_PATH also contains the path to libnetcdf; it is complaining about undefined symbols that should be found in libnetcdf.

Not all filters need to use libnetcdf, so check the Makefile to see if this one has it.

@WardF: my LD_LIBRARY_PATH already includes libnetcdf as I am testing an application that uses it.
LD_LIBRARY_PATH=/path/to/hdf5-1.14.1-2/lib:/path/to/netcdf-4.9.2/lib:/path/to/aws-sdk-cpp/lib64
To this I have appended even the reference to /path/to/netcdf-4.9.2/lib/plugins, however without resulting in success.
@DennisHeimbigner: I am going to check the Makefile of the plugins and to refer you, but I have found no solution so far. Let me say if you suggest something to do, please.

I have solved simply by forcing the library to link itself. Maybe, this affects only the intended plugins, as the reflexive link does not impact the building phase (while the library does not exist yet).
In pratice, I have used the following configuration:
./configure --prefix=/path/to/netcdf-4.9.2 --enable-s3 LDFLAGS="-L/path/to/aws-sdk-cpp/lib64 -laws-cpp-sdk-s3 -L/path/to/netcdf-4.9.2/lib -lnetcdf" CPPFLAGS=-I/path/to/aws-sdk-cpp/include CC=mpicc CPP=mpicxx
I think there is a more smart approach to solve the problem but, in the meantime, we can close this issue.

Try adding directory containing libnetcdf to LD_LIBRARY_PATH

@DennisHeimbigner: as I replied before, LD_LIBRARY_PATH has always included the path to libnetcdf in my tests; in fact, my application exploits it and they are regularly linked:
$ ldd /path/to/my/application
linux-vdso.so.1 (0x0000ffffa4d41000)
libnetcdf.so.19 => /path/to/libnetcdf.so.19 (0x0000ffffa4a00000)
libltdl.so.7 => /lib64/libltdl.so.7 (0x0000ffffa4ce3000)
libm.so.6 => /lib64/libm.so.6 (0x0000ffffa4c42000)
libc.so.6 => /lib64/libc.so.6 (0x0000ffffa4852000)
[...]
The problem is the link between each ncz plugin and libnetcdf: even if the LD_LIBRARY_PATH includes libnetcdf (useless during the building), the plugins are built without an explicit reference to it. In fact, the ldd tool applied to a filter does not report the connection:
$ ldd /path/to/netcdf-4.9.2/lib/plugins/lib__nczstdfilters.so
linux-vdso.so.1 (0x0000ffff879d1000)
libc.so.6 => /lib64/libc.so.6 (0x0000ffff877c5000)
/lib/ld-linux-aarch64.so.1 (0x0000ffff87994000)
I think that connection should rightly be established on loading the plugin, but this does not happended in my case.
Instead, adding the reference to libnetcdf to LDFLAGS, the filters includes an explicit connection even before loading the plugin (and many other links, in effect):
$ ldd /path/to/netcdf-4.9.2/lib/plugins/lib__nczstdfilters.so
linux-vdso.so.1 (0x0000ffff98cbd000)
libnetcdf.so.19 => /path/to/libnetcdf.so.19 (0x0000ffff98a00000)
libc.so.6 => /lib64/libc.so.6 (0x0000ffff98852000)
/lib/ld-linux-aarch64.so.1 (0x0000ffff98c80000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x0000ffff98600000)
libaws-cpp-sdk-s3.so => /path/to/libaws-cpp-sdk-s3.so (0x0000ffff98200000)
libhdf5_hl.so.310 => /path/to/libhdf5_hl.so.310 (0x0000ffff985ce000)
libhdf5.so.310 => /path/to/libhdf5.so.310 (0x0000ffff97c00000)
libm.so.6 => /lib64/libm.so.6 (0x0000ffff9852d000)
[...]
Then, I have no trouble to run the plugins.
Clearly, a smarter solution to link libnetcdf (only) to each ncz plugin, using default configuration, would be prefarable.
I thank you.

ok, please do ldd /path/to/netcdf-4.9.2/lib/plugins/lib__nczhdf5filters.so.0 to see where it thinks
libnetcdf is located.


Remove dead org URLs that redirect to gambling sites

I would recommend removing or somehow very clearly marking URLs of apparently-dead organizations that now redirect to gambling sites.  While this is not necessarily an indication the organization is dissolved, it's a good clue.  More to the point, we probably don't want to send anyone to gambling sites unexpectedly!
http://www.openmedianow.org/ currently redirects to emccan-dot-org
http://www.csol.org/ contents are now an online casino guide at same address

Hi @ShaneCurcuru, thanks for bringing this to our attention, we'll check the links we have to avoid these situations, thanks!

Fixed on the website, I still have to sync the web data with the repository data

See https://github.com/SOM-Research/OSSFoundations/issues/44


504 gateway timeout

Seems like my website will not load, and returns a 504 timeout after a while…

Update: It is now returning a 502 bad gateway

Hey, can you check now? 504 probably was because your tunnel got stuck or something but i restarted the server just in case (that's why you saw the 502 for a bit).
Btw, how the heck are you noticing downtime so quick?? Wth are you using localtunnel for and are you monitoring your localtunnel site like 24/7?? 😂

@TheBoroer lol I like to admire my projects so I check the website every few minutes 😂 also thanks it’s working again!

@TheBoroer I want to use it just for verifying server auths but it does not work as well, so we should use its alternatives?


166 HQDM Extensions Mechanism

See HQDM Model Extension Example for how to write an extension module.
(We could perhaps copy the example into the MC repo or create a better example.)

This functionality could do with unit testing, but seen as we don't have a test suite for HqdmObjectFactory yet, that may be asking too much of this PR.

I added a module containing the example extension (it's a separate module so that it gets built to a JAR for use by the examples module).
I wasn't able to get a JUnit test working in the examples module so I added it to src/main/java instead as a main program which runs successfully. There are instructions about how to run it in the class javadoc.

Perhaps at some point we can create a proper unit test if that's possible, but right now I think this might have to suffice.


SW-4468 Remove planting season months from UI

We're going to be replacing the admin-specified planting season start and end
months with a new user-editable planting season schedule. Since we won't be
bothering to set the start/end months given the new feature is coming up, stop
showing them in the UI.

Marked this as a draft while awaiting confirmation that it doesn't need to be gated by an opt-in feature flag.


Fixes merge clonflicts

Tested on a Linux system.

 Thank you for your submission, we really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.:x: supr sign nowYou have signed the CLA already but the status is still pending? Let us recheck it.

Fixes #1


[Aio] Client Side Interceptor For Unary Calls

Implements the unary unary interceptor for the client-side. Interceptors
can be now installed by passing them as a new parameter of the Channel
constructor or by giving them as part of the insecure_channel
function.
Interceptors are executed within an Asyncio task for making some work before
the RPC invocation, and after for accessing to the intercepted call that has
been invoked.
Main differences with the synchronous implementation.
How interceptors are added
There is a significative difference in how interceptors are being added in the Aio package and the interface provided by the synchronous package, while the last one allows composition the Aio package publishes a very naive implementation which only accepts the interceptors as a new constructor keyword, which can be implicitly given by using the insecure_channel primitive.
For example, the following snippet shows how interceptors would need to be installed from now on when Aio module is used.
channel = insecure_channel(..., interceptors=[MyInterceptor()])

Also fixes #21605.

@lidizheng and @gnossen PR updated with the following big changes:

Early access to the metadata an another RPC attributes from the caller is no longer allowable, so the caller would need to wait yes or yes till all interceptors have finished
Interceptors can make as many calls they want and return the relevant one
Interceptors can return a Response, under the hood we take care of returning this response as a generic finalized call.

I'm still being a skeptic of how cancellations are being handled right now, which basically is the best effort. Please give me your thoughts.

Will LGTM after tests added, and Python related tests passed. The Windows failure looks like a real one.

I will keep this PR blocked until this gets merged [1]
[1] https://github.com/grpc/grpc/pull/21506

Have you considered more of a Java-style interceptor design than mimicking the Go/(existing) Python-style?

Hi, @mehrdada I would be more than eager to know what are the strong points of implementing the interceptors using the Java Style rather than the one already used by Python or Go.
In my humble experience implementing an interceptor interface based on signal functions, which are triggered by the different events that happen during a gRPC call has some pain points. Having the code of the interceptors spread through different functions makes it less readable and more complicated, one of the examples is how to provide a context which would be shared by all of signal functions for identifying univocally a session. This problem is inherently resolved by the design proposed by Python and Go, where the context is held implicitly within the scope of the interceptor function.

@pfreixes The problem is in practice, is that except very simple interceptors that add something to header metadata (which are still easier in Java IMO, because you deal with all types of RPC all at once, as opposed to each of the four independently), you will need to create a fake machinery to imitate an ongoing stream yourself and do all the work and shoehorn this as the return value of intercepted RPCs, which is worse than the way Java is done. The other thing you usually want to intercept is to do things that happen at the end of an RPC (like logging or filing statistics), and those also need wrapping the stream object.

@pfreixes The Java-style interceptor can be implemented in one single cohesive class [1]. Does it mitigate the pain point of context management?
I personally is not a power user of interceptors, but I have investigated gRPC interceptor implementation in many languages. To me, the difference between Golang-style and Java-style is a trade-off between flexibility and complexity.
In Golang-style, users are responsible to drive the entire RPC (e.g. receive / send all messages, error handling, start/finish) [2]. For extra verbosity, users can inject logic at any point. For unary call interceptors, the Golang-style is simpler and more compact.
In Java-style, users can choose to only override the hook point they care (e.g. onHeaders, onError). It looks neater, but users can only inject logic to limited hook points. Also, the design of Java API is based on callback, so it requires less education to let users understand how to use interceptors.
I'm open to either option, Golang-style or Java-style. I can see the value of making simple usage more straightforward, but designing the hook points for callbacks won't be a simple task.
@mehrdada In practice, is Golang interceptors an overkill (do people use it for heavy jobs like caching / retrying or lighter jobs like checking headers / logging)? Is Java's interface (ClientCall and ClientCall.Listener) sufficient for your use cases?
[1] https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/header/HeaderClientInterceptor.java#L52
[2] https://github.com/grpc/grpc-go/blob/master/examples/features/interceptor/client/main.go#L71

Hi @lidizheng thanks for sharing the knowlege about the Java Interceptors style, I didn't see that you could return a new implementation [1] instance which would be used by all of the hooks, so having the chance of injecting any context at instantiation time and share it implicitly by all of the class methods.
In any case, I would be tempted to disagree in what is more or less verobosity. For example reproducing the same interceptor as the Java one but for Aio Python it would result on something like this:
class Interceptor(aio.UnaryUnaryClientInterceptor):
    async def intercept_unary_unary(self, continuation, client_call_details, request):
        client_call_details.metadata += ('foo', 'bar')
        call = await continuation(client_call_details, request)
        metadata = await call.initial_metadata()
        logger.info("header received from server {}".format(metadata))
        return call

So how much verbose it would be compared to an interceptor system based on hooks? Comparing it would Java might be a bit unfair, since Java as a language is per se more verbose than Python, but an API based on hooks even written with Python would need at least a minimal stuff that could become at least "equal" verbose than the previous example.
What kind of things?

The first step for returning the object holding the hooks implementation (for having a cohesive class for all of the hooks)
Declaration of the Hook class and its overridden methods.
Methods implementations

Regarding how much cognitive effort is required in the current one and how much cognitive effort would be required in a system based on hooks I have my doubts about which one would require more effort, but undoubtedly a one similar to the Java one would require some effort and it's not negligible.
On the other way, the Python/Go-style IMO gives a lot of freedom to the user which means that theoretically any pattern can be implemented without impacting the design of the interceptor API.
[1] https://github.com/grpc/grpc-java/blob/master/examples/src/main/java/io/grpc/examples/header/HeaderClientInterceptor.java#L44

@lidizheng last changes commented added into the PR. PTAL

@lidizheng any advice with the segmentation fault that Im getting in the Python tests for windows [1]?
The only way that I can think for debugging this would be using a Windows computer with all of the requirements, which it's gonna take me some time :(
[1] https://source.cloud.google.com/results/invocations/20a1cb85-e581-4e29-bf63-591c2d6a6dd0/targets/github%2Fgrpc%2Frun_tests%2Fpython_windows_opt_asyncio%2Fpy36_asyncio.test_aio.unit.interceptor_test.TestUnaryUnaryClientInterceptor/tests

@carl-mastrangelo do you have some ideas to share about interceptor use cases that fit the Java style better than Go/Python?

@lidizheng PTAL new commits added that fix #21605. Also thanks to that fix I've changed the way for reproducing timeouts - no more server.stop calls., which with a bit of luck will solve also the segfault that is breaking the Windows tests.

@pfreixes Unfortunately, the Windows segfault still exists...

@lidizheng I've manage to reproduce some segfaults in my Mac, I hope that the root cause is the same .. so, working on it.

@lidizheng segfault fixed, fighting with other CI problems and one test in Windows that is still giving issue

@pfreixes Good finding about the quirk of GC in Cython 👍

Ok, I would say that with the latest changes the PR would be in a ready state for get it merged if we decide to move forward with the current proposal.
The problem is that the CI is -if I'm not wrong- broken, @lidizheng yours PR are also failing in the same steps.

Known failures: https://github.com/grpc/grpc/issues/21626 https://github.com/grpc/grpc/issues/21627

The EasyCLA status seems stuck, let me try to close and reopen this PR.


Drop events that are out of date

Based on the PR https://github.com/bluesky/bluesky/pull/1505
Expected Behavior

Current Behavior

if you:

    use monitoring to get an event stream based on camonitor
    the ca events come in at a higher rate than we can emit the event model Events

Then the queue in ophyd gets backed up (because we have no meaningful back pressure, because we grab from the ca stack promptly we are defeating the CA back pressure). Because that queue ensues that they are processed in the order they are received, this means that processing things like "DMOV" also get delayed which causes other issues.

We conceived the monitoring in bluesky for "slow" things, but it gets used for "fast" things. I don't see a way to predict if something is going to be fast or slow apriopi so we can not protectively reject even setting up the bad cases so I think the only option we have is to implement something like this to ensure reliable operation.

Originally posted by @tacaswell  https://github.com/bluesky/bluesky/pull/1505#issuecomment-1090355100
Possible Solution

Steps to Reproduce (for bugs)

This should have (https://github.com/bluesky/bluesky/pull/1505#issuecomment-1030463301)

[ ] make the 'too old" time be configurable via kwargs in the Msg so that this can be selectively applied (some monitors are fast and likely to be problems, but dropping them is also OK which may be used in tandem with a monitor than is slow and catching everyone is critical)
[ ] add the ability to thread through a 1 in N logic (either only emitting every Nth or maybe probabilistically keeping emitting 90% of the time) .
[ ] sort out what happens when both are used (no callback older than drop dead time should go out, but then the question is the 1 in N of all events or of those young enough to be considered)
[ ] decide if timestamp will be a required kwarg or not
[ ] max age to be emitted (so once something is too stale, always drop on floor)
[ ] minimum gap between monitors (if we just emitted something, drop all new updates on the floor for some time)

additional possible consideration: as emit_event now accepts many readings rather than one thing, we might just filter instead of early return

What is the use case for this?

not sure, the current behavior section has this
    the ca events come in at a higher rate than we can emit the event model Events
and more can be found here https://github.com/bluesky/bluesky/pull/1505#issuecomment-1030458284

The use case is:

we are using put-complete to detect motion done
something is spamming us with updates faster than we can process them

there is a trampoline from the libca thread -> our thread so there is no protocol level backpressure (we could probably cap the queue and cause there to be some backpressure there)

eventually we get to the queue item that tells us the motion is done but it may be an important-for-operations amount delayed

Someplace we need to throttle the events and doing it at the bluesky level is reasonable.  I think one of our beamlines in monkey patching a version of this in so they can operate.

@tacaswell  is the error in the tests uncovering an unintended behavior, that needs to be fixed OR do we need to adjust the tests?

please post a GitHub link to the tests that are failing, and the traceback of the failure


Request: Dark Mode/Other Themes

This is a brilliant app, and I'd love to incorporate it into a standalone device for my Hi-Fi set up, but the current UI isn't something I'd want to incorporate into my current aesthetic.  I think, even for now, just allowing the user to be able to select a customer background color (ideally including a pre-defined dark theme) would suffice without a full on redesign.

+1 for dark mode, would love a totally black background as that would look awesome on devices with OLED / AMOLED displays.

https://www.oled-info.com/oled-devices/mobile-phones
https://www.oled-info.com/oled-devices/tablets
https://www.oled-info.com/oled-devices/other

For the spinning record suggest using either a coloured vinyl record or just a more shiny record against a black background.

I'd love to incorporate it into a standalone device for my Hi-Fi set up

It would be an awesome idea to use one of new Android touch control panel products like ITead's "Sonoff NSPanel Pro" or similar:
https://sonoff.tech/product/central-control-panel/nspanel-pro/
https://itead.cc/product/sonoff-nspanel-pro-smart-home-control-panel/
They are not too expensive and have already been hacked to install any Android app + ITead also sell a desk enclosure stand for it:
https://blakadder.com/nspanel-pro-sideload/
They have an internal USB OTG port but not sure if that can also be used as data for Android?
https://itead.cc/product/enclosure-stand/
Anyway, there are by now many similar "Android touch control panel" products for wall mounting on the market. See example:
https://expo.tuya.com/smart/gateway-control/central-control-system-(ccs)/(ccs)-panel/CT9cn950tvc6ri-CT9cn9oo7u78dh-CT9cnelxgr0n4h
Other than perhaps not all having USB port for data to Android OS, a other downside is that most do not have OLED displays.
PS: Note! Not all such Android touch control panel ship with Android OS as some instead use Linux or just some embedded OS.


Install problem on Lenovo X390 Yoga

First of all, thanks for your effort bringing new features to the Linux!
While installing for Lenovo Yoga X390 I've got problem transmitters not triggering at all on any of four configurations. Only RGB camera seems to work (got white LED presenting it on) but no IR beam. Any hints on how to make it work are highly appreciated.
The OS is Ubuntu 19.04
I believe my IR camera is under /dev/video2 (there are total four, even are cameras, odd video capture devices, whatever it means). The resulting output for v4l2-ctl is:
`
N317-PC07:~$ v4l2-ctl -d /dev/video2 --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
Type: Video Capture
[0]: 'GREY' (8-bit Greyscale)
	Size: Discrete 640x360
		Interval: Discrete 0.067s (15.000 fps)
		Interval: Discrete 0.033s (30.000 fps)

`

Some more information:
v4l2-ctl -d /dev/video2 --all Driver Info: 	Driver name      : uvcvideo 	Card type        : Integrated Camera: Integrated I 	Bus info         : usb-0000:00:14.0-8 	Driver version   : 5.0.21 	Capabilities     : 0x84a00001 		Video Capture 		Metadata Capture 		Streaming 		Extended Pix Format 		Device Capabilities 	Device Caps      : 0x04200001 		Video Capture 		Streaming 		Extended Pix Format Priority: 2 Video input : 0 (Camera 8: ok) Format Video Capture: 	Width/Height      : 640/360 	Pixel Format      : 'GREY' (8-bit Greyscale) 	Field             : None 	Bytes per Line    : 640 	Size Image        : 230400 	Colorspace        : sRGB 	Transfer Function : Default (maps to sRGB) 	YCbCr/HSV Encoding: Default (maps to ITU-R 601) 	Quantization      : Default (maps to Full Range) 	Flags             :  Crop Capability Video Capture: 	Bounds      : Left 0, Top 0, Width 640, Height 360 	Default     : Left 0, Top 0, Width 640, Height 360 	Pixel Aspect: 1/1 Selection: crop_default, Left 0, Top 0, Width 640, Height 360, Flags:  Selection: crop_bounds, Left 0, Top 0, Width 640, Height 360, Flags:  Streaming Parameters Video Capture: 	Capabilities     : timeperframe 	Frames per second: 30.000 (30/1) 	Read buffers     : 0

I've got some progress, both cameras work /dev/video0 (RGB) and /dev/video2 (IR) using fswebcam. IR camera gives 640x360 (assume it is correct) but still, no IR blasters working.

Got the same problem on my Lenovo Yoga S740

@pczekalski This might be related to #269. Could you try if the workaround https://github.com/boltgolt/howdy/issues/269#issuecomment-548105971 works for you?

Checked, still no luck.
I've set up Windows guest (Ubuntu 19.04 host) on VirtualBox and under the Windows 10 guest, Windows Hello works well. Wireshark installed on the host side but I'm stuck with configuring it as there is no "USB" interface in the options. Any hints on where to start configuration for sniffing?
Thanks in advance.

Checked, still no luck.
I've set up Windows guest (Ubuntu 19.04 host) on VirtualBox and under the Windows 10 guest, Windows Hello works well. Wireshark installed on the host side but I'm stuck with configuring it as there is no "USB" interface in the options. Any hints on where to start configuration for sniffing?
Thanks in advance.

You need to load the usbmon kernel module: modprobe usbmon

Thx,
OK - did a dump. In my case, it is a usbmon1 interface. However, I still don't get it if usbmon1 is a single device or a bunch of them connected to the bus. If suspect the second case as it seems to capture many devices: 1.4.0, 1.4.1, 1.5.0 and 1.5.2 (as showed up when loaded to wireshark). Any hints, how to filter to the particular device?

Both this and #269 are about Lenovo cameras and debugging the issue with USB messages, so marking this as a duplicate to keep the discussion in one place


"Disconnected from the server" message in team exercises

“You’re disconnected from the server” issues started happening to me on Artemis during modelling over the last week (when I click on “Submit” this always happens). I also know that some of my teammates had it and it indeed is very confusing:
I click on "Submit", get a red “Disconnected” status (which used to be "Connected" before I clicked on "Submit"), a red alert message “You are disconnected from the server, please check your Internet connection” but at the same time green success message “Your submission was successful”. If I try to submit again, the message persists.

we are not able to reproduce the issue any more


⚠ Bofrost.lu has degraded performance

In 5c362b1, Bofrost.lu (https://www.bofrost.lu) experienced degraded performance:

HTTP code: 200
Response time: 1027 ms

Resolved: Bofrost.lu performance has improved in 61f2cef after 6 minutes.


Update record

Hi Daniel!
Your material is very good, I just had a doubt but I still couldn't study your material, just based on the videos.
How does the user update? because it looks like it has only Inclusion and Exclusion

Hi,
Thanks. There's only a video that shows how to run the application.
Currently, there are only Adding and Removing functionalities without any edition. Perhaps I'll add in the near future.
Daniel

Obrigado!
thanks!


[mini.align] Align for commas but I have commas inside strings

Contributing guidelines

[X] I have read CONTRIBUTING.md
[X] I have read CODE_OF_CONDUCT.md
[X] I have updated 'mini.nvim' to latest version

Module(s)
mini.align
Description
What's a good modifier to align commas when I have commas in strings that should not be messed?
Neovim version
NVIM v0.11.0-dev-3338+gd7651b27d-Homebrew
Steps to reproduce

nvim -nu minimal.lua
...

Expected behavior
abc, "City, State",                 123
def, "Country",                     456
hij, "Another Country",             789
klm, "Another City, Another State", 012

Actual behavior
Tks for all the plugins!
I have a piece of code something like this:
abc, "City, State", 123
def, "Country", 456
hij, "Another Country", 789
klm, "Another City, Another State", 012

Trying to align it with  ga, gives me
abc, "City,             State",         123
def, "Country",         456
hij, "Another Country", 789
klm, "Another City,     Another State", 012

which is not what I wanted.
I tried to configure the split modifier manually but with no luck. Is there a good way to achieve this?

There is an "ignore" modifier. See more details here and the exported function for more control.
Its suggested application is like this:

gAip to start interactive align on paragraph.
, to enter split.
i to ignore some common splits.
Ensure the end result is what you'd expect and press <CR>.


Add a restart flag to config set

After setting config map changes, Cilium pods need to be restarted for the changes to take effect.
Currently, this is a manual step. Add a new flag with default set to true.

@aditighag Do you remember why you closed this? It seems it would have helped with https://github.com/cilium/cilium-cli/issues/165 (according to https://github.com/cilium/cilium-cli/pull/176).

@pchaigno The changes are already merged - https://github.com/cilium/cilium-cli/pull/154.


Mappings are ignored in rails 5

So I have been trying to make this work for few days now, nothing seems to work.
I have mappings defined in my model:
  settings do
    mappings dynamic: false do
      indexes :title, type: 'text'
      indexes :description, type: 'text'
      indexes :user, type: 'text' do
        indexes :name, type: 'text'
      end
    end
  end

But when I do:
Podcast.__elasticsearch__.delete_index! force: true
Podcast.__elasticsearch__.create_index! force: true
Podcast.__elasticsearch__.import force: true

and visit: http://localhost:9200/podcasts/_search?pretty=true&q=*:*&size=1000
I see all of the model data poured into the indexes(I need only title, description and user name).
What is the problem here?

在模型中定义一个as_indexed_json方法，
def as_indexed_json(options = {})     as_json(only: [:id, :parent_id, :name, :barcode])   end

Hi @IvRRimum, as @bysxiang suggests above, the mappings DSL only sets up the fields in your index with proper types, analyzers, etc. When you need to filter the properties of your model to be indexed, you have to use as_indexed_json — have a look at this chapter in the README: https://github.com/elastic/elasticsearch-rails/tree/master/elasticsearch-model#model-serialization

Hi @IvRRimum
Has using as_indexed_json achieved the functionality you were looking for?
If so, can we close this issue? If not, please let us know how we can help further.
Thanks


why oidc-client uses bitcoinjs-lib?

After a few months using this library, we found that oidc-client-js is using bitcoinjs-lib.
why?

where?

@brockallen
https://raw.githubusercontent.com/IdentityModel/oidc-client-js/dev/dist/oidc-client.js

This might be a transitive dependency from jsrsasign: https://github.com/IdentityModel/oidc-client-js/blob/dev/package.json#L48
It's not something this code base pulls in directly. This was also asked recently, so perhaps you could look in the issue history for more info on the prior discussion.

@brockallen thank you, could you refer me to the issue you mentioned above?

@brockallen thank you, would you please refer me to the issue you mentioned above?

There's a search field above. You and I would be searching for the same keywords.

I stumbled across this while looking at why the code was so big. Apparently there's some code that was used from bitcoinjs-lib? It borrows some functions (and gives credit) on some DSA functions? Just do a search for 'bitcoinjs' in the repository you'll find the references. Just for people who are stumbling on this.. Also, I did a search in the issues for bitcoin and there is none.

Anyone else end up here on a wild chase from a Blazor app? 😂

BTW, in some future release I plan to ditch jsrsasign -- it's just a matter of when I have the time to do so.

Anyone else end up here on a wild chase from a Blazor app? 😂

Wait what? lol


Implemented StackExchange.Redis.Strongname assembly

This fork replaced StackExchange.Redis with its Strongly named version in all three projects in the solution.  This does not require RedisSessionProvider to be strongly named, but allows RedisSessionProvider to be used in applications that already make use of the strongly named version of StackExchange.Redis.

@leewang0 any chance of a merge of this pull request?


feat(add): Stabilize MSRV-aware version req selection

What does this PR try to resolve?
This is part of #9930 for rust-lang/rfcs#3537
This will make it easier to maintain an MSRV-compliant Cargo.toml but leaves validation up to the user as the resolver will pick newer versions.
This helps the MSRV-aware workflows enumerated in
rust-lang/rfcs#3537
How should we test and review this PR?
As for determining if this is ready for stabilization:
By stabilizing this without the MSRV-aware resolver, this could be confusing to the workflow with an MSRV-compatible lockfile.
PR #13561 at least raises awareness of that discrepancy.
In general there was interest in the RFC discussions to stabilize this ASAP, regardless of what resolver direction we went.
There is an unresolved question on differences in the resolver vs cargo add for dealing with an unset rust-version (noted in the tracking issue). However, we are only stabilizing the cargo add side which is a very light two-way door as this is a UX-focused command and not a programmatic command.
This hasn't gotten much end-user acceptance testing but, as its UX focused, that seems fine (light, two way door)
As such, this seems like it is ready to stabilize.
Additional information

Err:10 https://ppa.launchpadcontent.net/ubuntu-toolchain-r/test/ubuntu jammy InRelease
  503  Service Unavailable [IP: <IP_ADDRESS> 443]

While the details of this still need a review, I figure we could do the high level "should we stabilize" conversation in parallel.
Before, when a user ran cargo add foo (no version req specified), we'd always make a version req out of the latest version.
With this change, we still give priority to the version req the user selected.  However, if they did not specify one, instead of always picking the latest version to make a version req from, instead we'll filter out versions incompatible with package.rust-version (falling back to rustc -V if unspecified).  If we select a non-latest version, we'll warn the user.  If we can't select a version, we will error.  The user can force the add to work by specifying the version req or passing --ignore-rust-version.
This does not include --update-rust-version.  I was planning on implementing that for both the resolver and cargo-add at the same time.
Differences with the resolver

This gives a hard error, rather than falling back to an incompatible version.  For an interactive command, I think this workflow is likely better.
This treats dependencies without a package.rust-version as compatible.  Being interactive, I think this is likely the best choice.  This is also a light two way door and we might want to consider changing the resolver to this behavior.  This discrepancy is being tracked in #9930.

This is part of RFC #3537. being tracked in #9930.  The intention with the RFC is that we could stabilize each individual piece, rather than waiting for everything to be ready.
@rfcbot fcp merge

Tiny UX question. Should users be aware of an older version of a dependency was chosen because of MSRV? Do we want to print something for that situation?

I'm not quite clear on how this works with the resolver. What happens if:

foo 1.0.0 is compatible with my msrv
foo 1.0.1 is not
run cargo add foo

Does it add foo = "1.0.0"? What happens with Cargo.lock, is it 1.0.0 or 1.0.1?

This is independent of the resolver.  The version requirement will be MSRV-compatible (foo = "1.0.0") while Cargo.lock will be set to 1.0.1.
For users who don't track MSRV-comptible dependencies in their lockfile, this is what they expect and things will be fine (until we change the resolver).
For users who do track MSRV-compatible dependencies, this removes one extra step for them.  They will have a valid Cargo.toml and will just need to work on their Cargo.lock.  They already know what to lock to for the first dependency.  They then only need to search the docs for any transitive dependencies.  They can also choose to use nightly to resolve as they want (either cargo +nightly -Zmsrv-policy add ... or git checkout HEAD -- Cargo.lock && cargo +nightly check -Zmsrv-policy).
So while this isn't a complete solution for everyone, until the resolver is stable, it does improvements for everyone.

@ehuss this does get me thinking that maybe we could update the
Locking 3 packages

message to
Locking 3 packages to latest versions
Locking 3 packages to latest rust-version compatible versions
Locking 3 packages to lowest versions

Depending on which resolve behavior is being invoked.

The FCP is complete. Thank you to everyone involved.
@bors r+

:pushpin: Commit 6e4e31bec05bf707f0e4123caa748174ba5d957f has been approved by weihanglo
It is now in the queue for this repository.

:hourglass: Testing commit 6e4e31bec05bf707f0e4123caa748174ba5d957f with merge 3d16d65e9327e189d5b3ba30a2b125ed9c3180b8...

:sunny: Test successful - checks-actions
Approved by: weihanglo
Pushing 3d16d65e9327e189d5b3ba30a2b125ed9c3180b8 to master...


[FEA] GetJsonObject: Collect all JSON cases in the issues; add test cases; go through existing get-json-object cases

Additional context
Epic issue: https://github.com/NVIDIA/spark-rapids-jni/issues/1823

Already added UT cases in feature branch.


Add target type in output of network logger plugin

It provides print logs according to TargetType.
Fixes #1853

          2 Warnings

:warning:
Consider also updating the Chinese docs. For Chinese translations, request the modified file(s) to be added to the list here for someone else to translate, if you can’t do so yourself.

:warning:
Any changes to library code should be reflected in the Changelog. Please consider adding a note there and adhere to the Changelog Guidelines.

          3 Messages

:book:
iOS: Executed 278 tests, with 0 failures (0 unexpected) in 13.109 (13.243) seconds

:book:
tvOS: Executed 278 tests, with 0 failures (0 unexpected) in 13.140 (13.268) seconds

:book:
macOS: Executed 278 tests, with 0 failures (0 unexpected) in 14.574 (14.709) seconds

  Generated by :no_entry_sign: Danger

Let me a quick update, I've checked the TODOs below.

[ ] CHANGELOG.md is updated.
[ ] NetworkActivityPlugin and CredentialsPlugin have the TargetType in the closure.
[ ] TargetType is not needed for AccessTokenPlugin.
[ ] The Output which I've changed is not used in the Plugins doc and it is not needed to update(I can add an example if needed).

Codecov Report

Merging #1866 into development will increase coverage by 1.27%.
The diff coverage is 77.77%.

@@               Coverage Diff               @@
##           development    #1866      +/-   ##
===============================================
+ Coverage        92.13%   93.41%   +1.27%
===============================================
  Files               25       25
  Lines              865      865
===============================================
+ Hits               797      808      +11
+ Misses              68       57      -11

Impacted Files
Coverage Δ

Sources/Moya/Plugins/NetworkLoggerPlugin.swift
93.44% <77.77%> (ø)
:arrow_up:

Sources/Moya/Response.swift
95.4% <0%> (+4.59%)
:arrow_up:

Sources/RxMoya/Observable+Response.swift
61.53% <0%> (+7.69%)
:arrow_up:

Sources/ReactiveMoya/SignalProducer+Response.swift
93.93% <0%> (+9.09%)
:arrow_up:

Sources/RxMoya/Single+Response.swift
100% <0%> (+12.5%)
:arrow_up:

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update cf9ee28...e4f5773. Read the comment docs.

@sunshinejr @hasankose Hey, how about we make target an optional parameter? This will keep the plugin working as it used to, and also enable users to filter by TargetType when they need.

@pedrovereza is it possible to do so without making a breaking change? Even if there is an optional parameter, you’d still need to handle it in the closure, right?

@sunshinejr Ah, you're right! Ignore me, I miss understood how the changes were being added here 😅

@pedrovereza no worries, this was something I didn't consider before so good question!

@hasankose alright I've pushed a small polish to the Changelog entry but we're good to go! Thanks again for looking into this, good timing with the new major release as well 👍