antocuni / capnpy

Other
45 stars 26 forks source link

Relative imports #20

Closed aldanor closed 1 year ago

aldanor commented 7 years ago

Both C++ capnp and pycapnp seem to support relative imports just fine (e.g. c++.capnp located next to the schema and imported as import "c++.capnp") -- wonder if there's a reason for disallowing that explicitly?

nickmyatt commented 5 years ago

Here is an example

$ ag --nonumbers --nocolor .
setup.py
from setuptools import setup

setup(
    setup_requires=["capnpy==0.5.4", "cython"],
    capnpy_schemas=[
        "a.capnp",
        "b.capnp",
    ],
)

b.capnp
@0xfb0588d58e690960;

using A = import "a.capnp";

struct B {
        a @0 :A.A;
}

a.capnp
@0xbf6d74819b5eaad0;

enum A {
        unknown @0;
}

capnp is apparently happy with the relative import

$ capnp compile -oc++ *.capnp
$ echo $?
0

but capnpy is not

$ python setup.py -vvv install
zip_safe flag not set; analyzing archive contents...

Installed /tmp/capnp-imports/.eggs/pypytools-0.6.1-py2.7.egg
Searching for docopt
Reading https://pypi.org/simple/docopt/
Downloading https://files.pythonhosted.org/packages/a2/55/8f8cab2afd404cf578136ef2cc5dfb50baa1761b68c9da1fb1e4eed343c9/docopt-0.6.2.tar.gz#sha256=49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491
Best match: docopt 0.6.2
Processing docopt-0.6.2.tar.gz
Writing /tmp/easy_install-YnxNF2/docopt-0.6.2/setup.cfg
Running docopt-0.6.2/setup.py -q bdist_egg --dist-dir /tmp/easy_install-YnxNF2/docopt-0.6.2/egg-dist-tmp-_DZ4El
zip_safe flag not set; analyzing archive contents...
Moving docopt-0.6.2-py2.7.egg to /tmp/capnp-imports/.eggs

Installed /tmp/capnp-imports/.eggs/docopt-0.6.2-py2.7.egg
Searching for py
Reading https://pypi.org/simple/py/
Downloading https://files.pythonhosted.org/packages/76/bc/394ad449851729244a97857ee14d7cba61ddb268dce3db538ba2f2ba1f0f/py-1.8.0-py2.py3-none-any.whl#sha256=64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa
Best match: py 1.8.0
Processing py-1.8.0-py2.py3-none-any.whl
Installing py-1.8.0-py2.py3-none-any.whl to /tmp/capnp-imports/.eggs

Installed /tmp/capnp-imports/.eggs/py-1.8.0-py2.7.egg
[capnpy] Compiling a.capnp
[capnpy] Compiling b.capnp
Traceback (most recent call last):
  File "setup.py", line 7, in <module>
    "b.capnp",
  File "/tmp/venv/lib/python2.7/site-packages/setuptools/__init__.py", line 145, in setup
    return distutils.core.setup(**attrs)
  File "/home/nickmyatt/.pyenv/versions/2.7.14/lib/python2.7/distutils/core.py", line 111, in setup
    _setup_distribution = dist = klass(attrs)
  File "/tmp/venv/lib/python2.7/site-packages/setuptools/dist.py", line 444, in __init__
    k: v for k, v in attrs.items()
  File "/home/nickmyatt/.pyenv/versions/2.7.14/lib/python2.7/distutils/dist.py", line 287, in __init__
    self.finalize_options()
  File "/tmp/venv/lib/python2.7/site-packages/setuptools/dist.py", line 732, in finalize_options
    ep.load()(self, ep.name, value)
  File "/tmp/capnp-imports/.eggs/capnpy-0.5.4-py2.7-linux-x86_64.egg/capnpy/compiler/distutils.py", line 29, in capnpy_schemas
    version_check=version_check)
  File "/tmp/capnp-imports/.eggs/capnpy-0.5.4-py2.7-linux-x86_64.egg/capnpy/compiler/distutils.py", line 38, in capnpify
    outfiles = [compiler.compile(f, convert_case, pyx, version_check) for f in files]
  File "/tmp/capnp-imports/.eggs/capnpy-0.5.4-py2.7-linux-x86_64.egg/capnpy/compiler/compiler.py", line 287, in compile
    pyx=pyx, version_check=version_check)
  File "/tmp/capnp-imports/.eggs/capnpy-0.5.4-py2.7-linux-x86_64.egg/capnpy/compiler/compiler.py", line 58, in generate_py_source
    src = m.generate()
  File "/tmp/capnp-imports/.eggs/capnpy-0.5.4-py2.7-linux-x86_64.egg/capnpy/compiler/module.py", line 71, in generate
    self.request.emit(self)
  File "/tmp/capnp-imports/.eggs/capnpy-0.5.4-py2.7-linux-x86_64.egg/capnpy/compiler/request.py", line 56, in emit
    self.requestedFiles[0].emit(m)
  File "/tmp/capnp-imports/.eggs/capnpy-0.5.4-py2.7-linux-x86_64.egg/capnpy/compiler/request.py", line 126, in emit
    self._declare_imports(m)
  File "/tmp/capnp-imports/.eggs/capnpy-0.5.4-py2.7-linux-x86_64.egg/capnpy/compiler/request.py", line 167, in _declare_imports
    assert ns.fullpath.startswith('/')
AssertionError

after patching compiler/request.py

167d166
<                 assert ns.fullpath.startswith('/')
169c168
<                 ns.modname = ns.fullpath[1:-6].replace('/', '.')
---
>                 ns.modname = ns.fullpath.lstrip('/')[:-6].replace('/', '.')

compilation works as expected, and the compiled schemas work

Python 2.7.14 (default, Nov 14 2017, 11:41:58) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import b
>>> b.B()
<B: (a = unknown)>

as OP mentions, can we get rid of the check?