Nanopb strip package option raises error at import - nanopb

I am struggling with nanopb to get the enum of another package which has * mangle_names:M_STRIP_PACKAGE in .options file. Here is a way to reproduce the problem easily :
I have a root_folder containing folder_A and folder_B.
In folder_A, I have file_A.proto and file_A.options :
file_A.proto:
syntax = "proto2";
package folder_A;
enum my_enum {
ENUM_0 = 0;
ENUM_1 = 1;
ENUM_2 = 2;
}
file_A.options:
* mangle_names:M_STRIP_PACKAGE
In folder_B, I have file_B.proto :
syntax = "proto2";
package folder_B;
import "folder_A/file_A.proto";
message dummy {
required folder_A.my_enum value = 1;
}
I try to generate proto file with the following command:
nanopb_generator.py -D . -I . -I .\folder_B\ .\folder_A\file_A.proto .\folder_B\file_B.proto
The script fails with error Exception: Could not find enum type folder_A_my_enum while generating default values for folder_B_dummy.
But if I remove the file_A.options, it works correctly.
Also if I replace the enum by a message, it works correctly even with file_A.options.
My question is : do you know if it is possible to use the option * mangle_names:M_STRIP_PACKAGE and import enum at the same time ?
I use nanopb-0.4.5.
Thank you !

Currently M_STRIP_PACKAGE does not work when there are imports from another package. I have added the problem to the issue tracker: https://github.com/nanopb/nanopb/issues/783
Imports with name mangling seem to work fine, as long as all imported files belong to the same package and have same name mangling settings.
It is also questionable whether stripping the package name from types is a good idea when you are using multiple package names. It sounds like a recipe for name collisions.

Related

How to apply a decorator with arguments to an imported function

This similar to a previous question but not quite.
Like the other question, I want to apply a decorator to an imported function, but in my case, my decorator requires arguments
Working
from flask_restx import Namespace
from . import exceptions as e
api = Namespace('v2', 'API Version 2' )
#api.errorhandler(e.MissingPrompt)
def handle_bad_requests(error):
'''Namespace error handler'''
logger.warning(error.log)
return({'message': error.specific}, error.code)
But I want to move handle_bad_requests() to its own file
so I want it like
from flask_restx import Namespace
from . import exceptions as e
api = Namespace('v2', 'API Version 2' )
#api.errorhandler(e.MissingPrompt)
e.handle_bad_requests # ??
I tried like the other answers here suggested like this
handle_bad_requests = api.errorhandler(e.handle_bad_requests, e.MissingPrompt)
But that just gives me an error I am sending too many arguments
I just discovered the answer nested within the comments of a previous answer
handle_bad_requests = api.errorhandler(e.MissingPrompt)(e.handle_bad_requests)
And that seems to work fine.
The double parentheses would never have occured to me

Unable to get IntelliJ's (Velocity) Code Template to work correctly with conditional variable assignment

I am attempting to improve a Scala Companion Object plus Case Class code generating template in IntelliJ 2021.3 (Build #IU-213.5744.223, built on November 27, 2021).
I would like to allow the user to be able to leave some of the input parameters unspecified (empty) and then have the template generate sane defaults. This is because the generated code can then be refactored by the client to something more pertinent later.
My question is this: Is there another way to approach achieving my goal than the way I show below using the Velocity #macro (which I got from here, and then doesn't appear to work anyway)?
With the current approach using the #marco, when I invoke it...
With:
NAME = "Longitude"
PROPERTY_1_VARIABLE = "value"
PROPERTY_1_TYPE - "Double"
The Scala code target:
final case class Longitude(value: Double)
With:
NAME = "Longitude"
PROPERTY_1_VARIABLE = ""
PROPERTY_1_TYPE - ""
The Scala code target using defaults for 2 and 3:
final case class Longitude(property1: Property1Type)
And here's my attempt to make it work with the IntelliJ (Velocity) Code Template:
#macro(condOp $check, $default)
#if ($check == "")
$default
#else
$check
#end
#end
#set (${PROPERTY_1_VARIABLE} = "#condOp(${PROPERTY_1_VARIABLE}, 'property1')")
#set (${PROPERTY_1_TYPE} = "#condOp(${PROPERTY_1_TYPE}, 'Property1Type')")
#if ((${PACKAGE_NAME} && ${PACKAGE_NAME} != ""))package ${PACKAGE_NAME} #end
final case class ${NAME} (${PROPERTY_1_VARIABLE}: ${PROPERTY_1_TYPE})
First, the IntelliJ popup box for entering the parameters correctly shows "Name:". And then incorrectly shows "default:" and "check". I have submitted a ticket with Jetbrains for this IntelliJ issue. Please vote for it, if you get a chance so it increases in priority.
And then when the macro finishes executing (I provide the Name of "LongLat", but leave the default and check parameters empty), I don't understand why I get the following gibberish.
package org.public_domain
${PROPERTY_1_TYPE})
Any guidance on fixing my current Velocity Code Template script or suggest another way to effectively approach solving the problem would be deeply appreciated.

Cannot resolve 'mathjs/number'

I am using Math.js to parse and evaluate a mathematical expression, and am following the example at https://mathjs.org/docs/custom_bundling.html#numbers-only as I only need basic number support. "mathjs": "^8.1.1", is listed in my package.json dependencies.
When I run the example code below, I get Module not found: Error: Can't resolve 'mathjs/number':
// use light-weight, numbers only implementations of functions
import { create, all } from 'mathjs/number'
const math = create(all)
Looks like maybe the documentation hasn't caught up. I was able to get this working by changing the line
import { create, all } from 'mathjs/number';
to
import { create, all } from 'mathjs/lib/esm/number';

python: Imported class does not change, when edited, saved and reimported

I'm new to Python and trying to understand classes. Not sure the following error is coming from the use of my IDE, which is Spyder, or if it is intended behaviour.
I define a class message in the file C:\mydir\class_def.py. Here is what the file contains:
class message:
def __init__(self,msg1,msg2):
self.msg1 = msg1
self.msg2 = msg2
I have another script were I want to execute code, called execute.py. In this script I import the class and make an instance of the class object. Here is the code from the script execute.py:
import os
os.chdir('C:\mydir')
from class_def import message
message_obj = message('Hello','world')
So far no problems!
Then I edit class_def.py to the following:
class message:
def __init__(self,msg1):
self.msg1 = msg1
and edit execute.py to match the new class, so removing one input tomessage:
import os
os.chdir('C:\mydir')
from class_def import message
message_obj = message('Hello')
and I get the following error:
TypeError: __init__() takes exactly 3 arguments (2 given)
It seems like Python keeps the old version of class_def.py and does not import the new one, even though it is saved.
Is this normal behaviour or is Spyder doing something funny?
If you have a .pyc file such as class_def.pyc, delete it.
I'd remove all .pyc files in your working directory and then try again. If that doesn't work, maybe you're not using the module you think you are? To be certain try something like:
import myModule
print myModule.__file__ #This will give you the path to the .pyc file your program loaded
#or
import myModule
import os
print os.path.dirname(myModule.__file__)
try those out so you can be certain that you're actually using the file you're modifying. Hope that helps!

neo4jphp: Cannot instantiate abstract class Everyman\Neo4j\Transport

maybe a simple question but for me as starter with Neo4j a hurdle. I installed the neo4jphp with composer in the same directory as my application. Vendor-Subfolder has been created and the everyman/neo4j folder below is available. For a first test I used this code snippet from the examples:
spl_autoload_register(function ($className) {
$libPath = 'vendor\\';
$classFile = $className.'.php';
$classPath = $libPath.$classFile;
if (file_exists($classPath)) {
require($classPath);
}
});
require('vendor/autoload.php');
use everyman\Neo4j\Client,
everyman\Neo4j\Transport;
$client = new Client(new Transport('localhost', 7474));
print_r($client->getServerInfo());
I always stumple upon the error
Fatal error: Cannot instantiate abstract class Everyman\Neo4j\Transport
Googling brought me to a comment from Josh Adell stating
You can't instantiate Everyman\Neo4j\Transport, since it is an abstract class. You must instantiate Everyman\Neo4j\Transport\Curl or Everyman\Neo4j\Transport\Stream depending on your needs
So I thought I just need to alter the use-statements to
use everyman\Neo4j\Client,
everyman\Neo4j\Transport\Curl;
but this doesnt work, debugging shows, that the autoloader only get "Transport.php" instead of "everyman\Neo4j\Transport\Curl.php". For "Client.php" its still working ("vendor\everyman\Neo4j\Client.php") so I am guessing that the use-statement is wrong or the code is not able to handle an additional subfolder-structure.
Using
require('phar://neo4jphp.phar');
works fine but I read that this is deprecated and should be replaced by composer / autoload.
Anyone has a hint what to change or had the same problem?
Thanks for your time,
Balael
Curl is the default transport. You only need to instantiate your own Transport object if you want to use Stream instead of Curl. If you really want to instantiate your own Curl Transport, the easiest change to your existing code is to modify the use statement to be:
use everyman\Neo4j\Client,
everyman\Neo4j\Transport\Curl as Transport;
Also, you don't need to register your own autoload function if you are using the Composer package. vendor/autoload.php does that for you.
Thanks Josh, I was trying but it seems I still stuck somewhere. I am fine with using the default CURL - so I shrinked the code down to
require('vendor/autoload.php');
use everyman\Neo4j\Client;
$client = new Everyman\Neo4j\Client('localhost', 7474);
print_r($client->getServerInfo());`
The folder structure is main (here are the files and the composer.json with the content
{
"require": {
"everyman/Neo4j": "dev-master"
}
}
and in the subfolder "vendor" we have the "autoload.php" and the subfolder everyman with the related content. When I run the file I come out with
Fatal error: Class 'Everyman\Neo4j\Client' not found
which does not happen when I have the autoloadfunction. I guess I made a mistake somewehere - can you give me a hint?
Thanks a lot, B
Hmmm... I was just trying around and it seems the Transport CLASS is not needed in the use-statement and the class instantiation. This seems to work:
require('vendor/autoload.php');
use everyman\Neo4j\Client;
$client = new Client();
print_r($client->getServerInfo());
also valid for having a dedicated server/port:
$client = new Everyman\Neo4j\Client('localhost', 7474);
If you have more input I would be happy to learn more - thanks, all input & thoughts are very appreciated.
Balael