How can I modify/merge Jinja2 dictionaries? - merge

I have a Jinja2 dictionary and I want a single expression that modifies it - either by changing its content, or merging with another dictionary.
>>> import jinja2
>>> e = jinja2.Environment()
Modify a dict: Fails.
>>> e.from_string("{{ x[4]=5 }}").render({'x':{1:2,2:3}})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "jinja2/environment.py", line 743, in from_string
return cls.from_code(self, self.compile(source), globals, None)
File "jinja2/environment.py", line 469, in compile
self.handle_exception(exc_info, source_hint=source)
File "<unknown>", line 1, in template
jinja2.exceptions.TemplateSyntaxError: expected token
'end of print statement', got '='
Two-stage update: Prints superfluous "None".
>>> e.from_string("{{ x.update({4:5}) }} {{ x }}").render({'x':{1:2,2:3}})
u'None {1: 2, 2: 3, 4: 5}'
>>> e.from_string("{{ dict(x.items()+ {3:4}.items()) }}").render({'x':{1:2,2:3}})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "jinja2/environment.py", line 868, in render
return self.environment.handle_exception(exc_info, True)
File "<template>", line 1, in top-level template code
TypeError: <lambda>() takes exactly 0 arguments (1 given)
Use dict(x,**y): Fails.
>>> e.from_string("{{ dict((3,4), **x) }}").render({'x':{1:2,2:3}})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "jinja2/environment.py", line 868, in render
return self.environment.handle_exception(exc_info, True)
File "<template>", line 1, in top-level template code
TypeError: call() keywords must be strings
So how does one modify the dictionary x in Jinja2 by changing an attribute or merging with another dictionary?
This question is similar to: How can I merge two Python dictionaries as a single expression? -- insofar as Jinja2 and Python are analogous.

I found another solution without any extension.
{% set _dummy = x.update({4:5}) %}
It makes x updated. Don't use _dummy.

Sounds like the Jinja2 "do" statement extension may help. Enabling this extension would allow you to rewrite:
{{ x.update({4:5}) }} {{ x }}
as
{% do x.update({4:5}) %} {{ x }}
Example:
>>> import jinja2
>>> e = jinja2.Environment(extensions=["jinja2.ext.do",])
>>> e.from_string("{% do x.update({4:5}) %} {{ x }}").render({'x':{1:2,2:3}})
u' {1: 2, 2: 3, 4: 5}'
>>>

I added a filter to merge dictionaries, namely:
>>> def add_to_dict(x,y): return dict(x, **y)
>>> e.filters['add_to_dict'] = add_to_dict
>>> e.from_string("{{ x|add_to_dict({4:5}) }}").render({'x':{1:2,2:3}})
u'{1: 2, 2: 3, 4: 5}'

Related

ruamel.yaml ComposerError when using alias/ as name

I am trying to parse the following document
hello:
there: &there_value 1
foo:
*there_value: 3
This gets correctly parsed with the safe loader:
>>> from ruamel.yaml import YAML
>>> document = """
... hello:
... there: &there_value 1
... foo:
... *there_value: 3
"""
>>> yaml=YAML(typ="safe")
>>> yaml.load(document)
{'hello': {'there': 1}, 'foo': {1: 3}}
The round-trip (standard) loader throws an error:
>>> yaml=YAML()
>>> yaml.load(document)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "...\site-packages\ruamel\yaml\main.py", line 434, in load
return constructor.get_single_data()
File "...\site-packages\ruamel\yaml\constructor.py", line 119, in get_single_data
node = self.composer.get_single_node()
File "...\site-packages\ruamel\yaml\composer.py", line 76, in get_single_node
document = self.compose_document()
File "...\site-packages\ruamel\yaml\composer.py", line 99, in compose_document
node = self.compose_node(None, None)
File "...\site-packages\ruamel\yaml\composer.py", line 143, in compose_node
node = self.compose_mapping_node(anchor)
File "...\site-packages\ruamel\yaml\composer.py", line 223, in compose_mapping_node
item_value = self.compose_node(node, item_key)
File "...\site-packages\ruamel\yaml\composer.py", line 117, in compose_node
raise ComposerError(
ruamel.yaml.composer.ComposerError: found undefined alias 'there_value:'
in "<unicode string>", line 6, column 3:
*there_value: 3
^ (line: 6)
I am using Python 3.8.10, ruamel.yaml version 0.17.21.
As Anthon suggested in their comment, : is a valid character for an anchor,
so *there_value: is looking for there_value: which is not defined, only there_value is.
The solution is to add a space after the anchor, *there_value :.
hello:
there: &there_value 1
foo:
*there_value : 3
This loads correctly both with round-trip and with safe.

pycairo error: “no current point defined” when trying to use TeeSurface

I'm trying to use a cairo.TeeSurface (pycairo version '1.21.0') to redirect input to multiple surfaces, but I cannot make it work, here is my code:
>>> import cairo
>>> s1 = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500,500)
>>> s2 = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500,500)
>>> s3 = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500,500)
>>> s = cairo.TeeSurface(s1)
>>> s.add(s2)
>>> s.add(s3)
>>> c = cairo.Context(s)
After above iniziatilation if I try to draw a line I get an error:
>>> c.rel_line_to(100,100)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
cairo.Error: no current point defined
I tried to set explicitly a point but I get the same error:
>>> c.move_to(10,10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
cairo.Error: no current point defined
For sure I must have misunderstood something, any clue would be appreciated.

Cannot cast ListType[tuple(float64 x 2)] to list(tuple(float64 x 2)) in numba

Hello I am trying to use typed List in numba v46.0
>>> from numba.typed import List
>>> from numba import types
>>> mylist = List.empty_list(item_type=types.Tuple((types.f8, types.f8)))
>>> mylist2 = List.empty_list(item_type=types.List(dtype=types.Tuple((types.f8, types.f8))))
>>> mylist2.append(mylist)
but I got the following error, I am wondering how to fix it?
Traceback (most recent call last): File "", line 1, in
File
"/usr/local/lib/python3.7/site-packages/numba/typed/typedlist.py",
line 223, in append
_append(self, item) File "/usr/local/lib/python3.7/site-packages/numba/dispatcher.py", line
401, in _compile_for_args
error_rewrite(e, 'typing') File "/usr/local/lib/python3.7/site-packages/numba/dispatcher.py", line
344, in error_rewrite
reraise(type(e), e, None) File "/usr/local/lib/python3.7/site-packages/numba/six.py", line 668, in
reraise
raise value.with_traceback(tb) numba.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend) Internal error at
. Failed in
nopython mode pipeline (step: nopython mode backend) Cannot cast
ListType[tuple(float64 x 2)] to list(tuple(float64 x 2)): %".24" =
load {i8*, i8*}, {i8*, i8*}* %"item"
File
"../../usr/local/lib/python3.7/site-packages/numba/listobject.py",
line 434:
def impl(l, item):
casteditem = _cast(item, itemty)
the following should work
mylist2 = List.empty_list(item_type=types.ListType(itemty=types.Tuple((types.f8, types.f8))))

How make a correct query from pymongo

I am using pymongo to subset a collection in mongodb, I am having problems with the syntax of the query, this is my query:
import pymongo
client=pymongo.MongoClient("localhost",27017)
db=client("publications")
collec=db("zikaVirus2")
pipeline=db.collec.aggregate([
{"$match":{"fullText":{"$exists": "true"}}},
{"$out": "pub_fulltext"}
])
db.pub_fulltext.aggregate(pipeline)
I am getting this error:
Traceback (most recent call last):
File "genColFulltext.py", line 3, in <module>
db=client("publications")
TypeError: 'MongoClient' object is not callable
UPDATE 1
If I do
import pymongo
client=pymongo.MongoClient("localhost",27017)
db=client.publications
collec=db.zikaVirus2
pipeline=db.collec.aggregate([
{"$match":{"fullText":{"$exists": "true"}}},
{"$out": "pub_fulltext"}
])
db.pub_fulltext.aggregate(pipeline)
I get
Traceback (most recent call last):
File "genColFulltext.py", line 11, in <module>
db.pub_fulltext.aggregate(pipeline)
File "/home/danielo/.local/lib/python3.5/site-packages/pymongo /collection.py", line 2397, in aggregate
**kwargs)
File "/home/danielo/.local/lib/python3.5/site-packages/pymongo/collection.py", line 2242, in _aggregate
common.validate_list('pipeline', pipeline)
File "/home/danielo/.local/lib/python3.5/site-packages/pymongo/common.py", line 428, in validate_list
raise TypeError("%s must be a list" % (option,))
TypeError: pipeline must be a list
UPDATE 2
This code runs without problems, but it make nothing of his purpose, the collection pub_fulltext have anything, when it should have data.
import pymongo
client=pymongo.MongoClient("localhost",27017)
db=client.publications
collec=db.zikaVirus2
pipeline=db.collec.aggregate([
{"$match":{"fullText":{"$exists": "true"}}},
{"$out": "pub_fulltext"}
])
for item in pipeline:
db.pub_fulltext.aggregate(item)
Then I try this:
import pymongo
client=pymongo.MongoClient("localhost",27017)
db=client.publications
collec=db.zikaVirus2
pipeline=[db.collec.aggregate([
{"$match":{"fullText":{"$exists": "true"}}},
{"$out": "pub_fulltext"}
])]
for item in db.collection.aggregate(pipeline):
db.collection.aggregate(item)
Getting this error:
Traceback (most recent call last):
File "genColFulltext.py", line 10, in <module>
for item in collection.aggregate(pipeline):
Traceback (most recent call last): File "genColFulltext.py", line 10, in <module>
for item in db.collection.aggregate(pipeline): File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pymongo/collection.py", line 2397, in aggregate
**kwargs) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pymongo/collection.py", line 2304, in _aggregate
client=self.__database.client) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pymongo/pool.py", line 584, in command
self._raise_connection_failure(error) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pymongo/pool.py", line 745, in _raise_connection_failure
raise error File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pymongo/pool.py", line 579, in command
unacknowledged=unacknowledged) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pymongo/network.py", line 114, in command
codec_options, ctx=compression_ctx) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pymongo/message.py", line 679, in _op_msg
flags, command, identifier, docs, check_keys, opts) bson.errors.InvalidDocument: Cannot encode object: <pymongo.command_cursor.CommandCursor object at 0x1008e4198>

pyang and JNC integration

I'm trying to integrate JNC and Pyang. As the jnc steps describes I have copied jnc.py under PYANG_HOME/pyang/plugins. I try to generate the java classes for simple.yang under $JNC_HOME/examples/yang using the command
pyang -f jnc --jnc-output src/gen/simple yang/simple.yang
facing the following error,
Traceback (most recent call last):
File "D:/tools/pyang-master/bin/pyang", line 434, in <module>
run()
File "D:/tools/pyang-master/bin/pyang", line 408, in run
emit_obj.emit(ctx, modules, fd)
File "C:\Users\Siva\AppData\Local\Programs\Python\Python35-32\lib\site-packages\pyang-1.7-py3.5.egg\pyang/plugins\jnc.py", line 208, in emit
if module_stmt in (imported + included):
TypeError: unsupported operand type(s) for +: 'map' and 'map'
Anyone faced this kind of issue. please let me know how to fix this.
Problem is with map implementation:
map in Python-3 returns an iterator, while map in Python 2 returns a list:
Python 2:
>>> type(map(abs, [43, -12, 13, -14]))
<type 'list'>
Python 3:
>>> type(map(abs, [99, -52, 32, -34, 13]))
<class 'map'>
You can edit file jnc.py and change code as below:
for (module_stmt, rev) in self.ctx.modules:
if module_stmt in (imported + included):
module_set.add(self.ctx.modules[(module_stmt, rev)])
for (module_stmt, rev) in self.ctx.modules:
if module_stmt in (included):
module_set.add(self.ctx.modules[(module_stmt, rev)])
if module_stmt in (imported):
module_set.add(self.ctx.modules[(module_stmt, rev)])