Skip to content
This repository has been archived by the owner on Mar 8, 2023. It is now read-only.

Commit

Permalink
Merge pull request #72 from uber/imports
Browse files Browse the repository at this point in the history
Add support for including other Thrift files.
  • Loading branch information
abhinav committed Nov 3, 2015
2 parents 0b25138 + 432a28c commit e33a58d
Show file tree
Hide file tree
Showing 18 changed files with 842 additions and 127 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ env/
_build
*.swp
node_modules
*.c
*.so
.benchmarks/
.coverage
5 changes: 5 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Releases
0.6.0 (unreleased)
------------------

- ``include`` statements are now supported. For more information, see
:ref:`including-modules`.
- Added support for message envelopes. This makes it possible to talk with
standard Apache Thrift services and clients. For more information, see
:ref:`calling-apache-thrift`.
Expand All @@ -19,6 +21,9 @@ Releases
``FunctionSpec``.
- ``ServiceSpec`` now provides a ``lookup`` method to look up ``FunctionSpecs``
by name.
- Removed the ``force`` option on ``Loader.load``.
- In generated modules, renamed the ``types``, ``constants`` and ``services``
attributes to ``__types__``, ``__constants__``, and ``__services__``.


0.5.2 (2015-10-19)
Expand Down
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: test lint docs docsopen clean
.PHONY: test lint docs docsopen clean install

test_args := \
--cov thriftrw \
Expand Down Expand Up @@ -29,3 +29,9 @@ clean:
find tests thriftrw -name \*.c -delete
find tests thriftrw -name \*.so -delete
make -C docs clean

install:
pip install -r requirements.txt
pip install -r requirements-dev.txt
pip install -r requirements-test.txt
pip install -e .
93 changes: 90 additions & 3 deletions docs/overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -155,21 +155,54 @@ The generated module contains two top-level functions ``dumps`` and ``loads``.
If the method name was not recognized or any other payload parsing
errors.

.. py:attribute:: services
.. py:attribute:: __services__
Collection of all classes generated for all services defined in the source
thrift file.

.. py:attribute:: types
.. versionchanged:: 0.6

Renamed from ``services`` to ``__services__``.

.. py:attribute:: __types__
Collection of all classes generated for all types defined in the source
thrift file.

.. py:attribute:: constants
.. versionchanged:: 0.6

Renamed from ``types`` to ``__types__``.

.. py:attribute:: __includes__
Collection of modules which were referenced via ``include`` statements in
the generated module.

.. versionadded:: 0.6

.. py:attribute:: __constants__
Mapping of constant name to value for all constants defined in the source
thrift file.

.. versionchanged:: 0.6

Renamed from ``constants`` to ``__constants__``.

Includes
~~~~~~~~

For an include::

include "./shared.thrift"

The generated module will include a top-level attribute ``shared`` which
references the generated module for ``shared.thrift``.

Note that paths in include statements are relative to the directory containing
the Thrift file and they must be in the from ``./foo.thrift``,
``./foo/bar.thrift``, ``../baz.thrift``, and so on.

Structs
~~~~~~~

Expand Down Expand Up @@ -413,6 +446,60 @@ Thrift Type Primitive Type
``exception`` ``dict``
============= ==============

.. _including-modules:

Including other Thrift files
----------------------------

Types, services, and constants defined in different Thrift files may be
referenced by using ``include`` statements with paths **relative to the current
.thrift file**. The paths must be in the form ``./foo.thrift``,
``./foo/bar.thrift``, ``../baz.thrift``, and so on.

Included modules will automatically be compiled along with the
module that included them, and they will be made available in the generated
module with the base name of the included file.

For example, given::

// shared/types.thrift

struct UUID {
1: required i64 high
2: required i64 low
}

And::

// services/user.thrift

include "../shared/types.thrift"

struct User {
1: required types.UUID uuid
}

You can do the following

.. code-block:: python
service = thriftrw.load('services/user.thrift')
user_uuid = service.shared.UUID(...)
user = service.User(uuid=user_uuid)
# ...
Also note that you can ``load()`` Thrift files that have already been loaded
without extra cost because the result is cached by the system.

.. code-block:: python
service = thriftrw.load('services/user.thrift')
types = thriftrw.load('shared/types.thrift')
assert service.types is types
.. _calling-apache-thrift:

Calling Apache Thrift
Expand Down
40 changes: 5 additions & 35 deletions tests/compile/test_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,41 +21,11 @@
from __future__ import absolute_import, unicode_literals, print_function

import pytest
from functools import partial

from thriftrw.idl import Parser
from thriftrw.protocol import BinaryProtocol
from thriftrw.compile import Compiler
from thriftrw.errors import ThriftCompilerError


@pytest.fixture
def parse():
return Parser().parse


@pytest.fixture
def compile(request):
return partial(Compiler(BinaryProtocol()).compile, request.node.name)


@pytest.fixture
def loads(parse, compile):
return (lambda s: compile(parse(s)))


def test_include_disallowed(loads):
with pytest.raises(ThriftCompilerError) as exc_info:
loads('''
namespace py foo
namespace js bar
include "foo.thrift"
''')

assert 'thriftrw does not support including' in str(exc_info)


def test_unknown_type(loads):
with pytest.raises(ThriftCompilerError) as exc_info:
loads('''
Expand Down Expand Up @@ -118,14 +88,14 @@ def test_services_and_types(loads):
'z': [m.x, m.y],
'x': 42,
'y': 123,
} == m.constants
} == m.__constants__

assert (
m.types == (m.Foo, m.Bar) or
m.types == (m.Bar, m.Foo)
m.__types__ == (m.Foo, m.Bar) or
m.__types__ == (m.Bar, m.Foo)
)

assert (
m.services == (m.A, m.B) or
m.services == (m.B, m.A)
m.__services__ == (m.A, m.B) or
m.__services__ == (m.B, m.A)
)
Loading

0 comments on commit e33a58d

Please sign in to comment.