[C++-sig] Different behavior between local import and import from python-path

Benedikt Tutzer benedikt_tutzer at yahoo.de
Thu Jul 4 10:28:22 EDT 2019


Hello,

A few months ago I published Python wrappers for Yosys 
(https://github.com/YosysHQ/yosys). These can be used in two ways:

 1. Use Yosys in Python code by importing it and using it as a library
 2. Start the Yosys shell (regular command-line interaction) and load
    python code by specifying a source file. In that source file, one
    can implement passes by inheriting from the Pass class and these
    passes are then available in the Yosys shell.

This works well and was already merged into the main Yosys repo.

However, there is an issue I cannot wrap my head around. When Yosys is 
installed, I copy the shared library .so file together with a minimal 
__init__.py to /usr/lib/python3.5/site-packages/pyosys. I can then use 
that by writing

> from pyosys import libyosys as ys
This works great for case 1. I also need that import for case 2, so that 
users can inherit from the Pass class and use Yosys data structures. The 
import seems to work, but as soon as a command is issued, an exception 
is thrown. This exception seems not to concern the interoperability with 
Python, but it does not appear when I copy the .so file to the current 
working directory and import it by saying
> import libyosys as ys
In that case, everything is well and the whole thing works. The Pass 
defined in Python shows up in the Pass-list, can be executed and 
successfully interacts with the data structures created by C++ passes.

The obvious place to look would be the __init__.py file, since that is 
the only thing that is executed when importing from the path but not 
executed when importing from the local library, right? But all I do in 
the init file is:

> import os
> import sys
> sys.setdlopenflags(os.RTLD_NOW | os.RTLD_GLOBAL)
>
> __all__ = ["libyosys"]
And if I remove the first lines it doesn't work either, so they cannot 
(solely) be at fault.

Any other reason why the two ways to import would differ?

The exception thrown is a std::out_of_range exception where an empty 
vector is accessed at position 171. I introduced some debug-output and 
notice that the vector actually contains 179 elements. Is it somehow 
possible that Python and C++ see a different version of the vector? It 
is filled from C++ before calling any Python code and there is no place 
in the code where anything is removed from the vector, so I don't see 
why it should shrink in size.

There is a Github issue about this where you can find a minimal example, 
but you need to build yosys and it is kind of big -> 
https://github.com/YosysHQ/yosys/issues/1094

The Python wrappers are defined in kernel/python_wrappers.cc, but it is 
auto-generated from a Python-script during the build, so I attached it 
for your convenience.

Any thoughts and ideas are highly welcome! I am completely stuck and 
don't know where to start debugging.

BR

Benedikt

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20190704/b8ec136f/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: python_wrappers.cc
Type: text/x-c++src
Size: 561529 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20190704/b8ec136f/attachment-0001.cc>


More information about the Cplusplus-sig mailing list