Giter Site home page Giter Site logo

hdima / erlport Goto Github PK

View Code? Open in Web Editor NEW
621.0 34.0 132.0 1.2 MB

ErlPort - connect Erlang to other languages

Home Page: http://erlport.org

License: BSD 3-Clause "New" or "Revised" License

Python 35.30% Ruby 23.11% Shell 1.17% Erlang 37.53% Makefile 2.89%

erlport's Introduction

ErlPort - connect Erlang to other languages

ErlPort is a library for Erlang which helps connect Erlang to a number of other programming languages. Currently supported external languages are Python and Ruby. The library uses Erlang port protocol to simplify connection between languages and Erlang external term format to set the common data types mapping.

The following is an example ErlPort session for Python:

erl

1> {ok, P} = python:start(). {ok,<0.34.0>} 2> python:call(P, sys, 'version.__str__', []). <<"2.7.3 (default, Aug 1 2012, 05:14:39) n[GCC 4.6.3]">> 3> python:call(P, operator, add, [2, 2]). 4 4> python:stop(P). ok

Check http://erlport.org for more information:

Feedback

Please use the following channels for reporting bugs, offering suggestions or feedback:

erlport's People

Contributors

etrepum avatar hdima avatar japerk avatar johnlinvc avatar nifoc avatar pib avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

erlport's Issues

Send message example not working

Hello,

I'm trying to run 'Send messages from Erlang to Python example', but I get the following errors in Erlang shell:

exception error: {python,'builtins.TypeError',"bytes object expected",
[{"c:\Program Files\erl7.2.1\lib\erlport-0.9.8\priv\python3\erlport\erlterms.py",
66,"new",
"raise TypeError("bytes object expected")"},
{"C:\Users\estjako\PycharmProjects\untitled\handler.py",
8,"register_handler","return Atom("ok")"},
{"c:\Program Files\erl7.2.1\lib\erlport-0.9.8\priv\python3\erlport\erlang.py",
239,"_incoming_call",
"result = Atom(b"r"), mid, self.encoder(f(_map(self.decoder, args)))"},
{"c:\Program Files\erl7.2.1\lib\erlport-0.9.8\priv\python3\erlport\erlang.py",
244,"_call_with_error_handler",
"function(_args)"}]}
in function erlport:call/3 (src/erlport.erl, line 234)

I'm currently using Erlang/OTP 18 and Python 3.4.

Thank you!

Not working in Windows

Using Windows XP and Windows 7, Erlport can't find the python interpreter.
It works without a hitch in Debian.

I've tried various combinations of environment variables and python:start() options.
python:start([{python, "C:\Python27"}]). and all combinations of that directory.
error: invalid_option, {python, "c:\Python27"}, not_found}}
If I add a \ to the end of that path, it just sits there doing nothing forever until I kill the process.

It looks like ERLPORT_PYTHON is the correct env var to set the interpreter path,
{error,{invalid_env_var,{"ERLPORT_PYTHON","c:\python27"), not_found}}

After messing around with it for a while, I found the root cause is a missing python entry in the PATH env var. after adding the python folder to PATH, I was able to run erlport without setting any options.

Just posting this info for other people who may have this problem.

Could not compile erlport

I am getting this error compiling erlport:

** (Mix) Could not compile dependency :erlport, "/Users/mladen/.mix/rebar3 bare compile --paths "/Users/mladen/work/inSITE_Search/_build/dev/lib/*/ebin"" command failed.

I am getting this on a freshly installed macOS high sierra, while i never got this error on other Macs i tried.
I only found one user with similar error but without much luck fixing it:
https://translate.google.com/translate?sl=auto&tl=en&js=y&prev=_t&hl=sr&ie=UTF-8&u=https%3A%2F%2Fteratail.com%2Fquestions%2F114967&edit-text=&act=url

I am using default python that comes with mac (2.7) and i don't have erlport installed via pip.
I also don't get any error besides "could not compile" or i don't know here to look for error logs.

How to install erlport.erlterms in Python 2.7 in Windows 10?

Hi Dev team and All,
I tried pip install erlport.erlterms. It didn't work. Then I downloaded the binary package and tried python -m pip install . There came an error saying not found setup.py. How can I have erlport.erlterms installed?
Help please! Thank you very much.

Best regards,
Jianliang

Erlport 1.0 release?

The website says 1.0 alpha is out, but that's an old version. We've been using erlport pretty happily in production for over a year, and I think you should release a new version.

Also, the rubygems and pypi packages should be updated. Pypi is at 0.6, which is very old.

Erlport dependency not compiling on Erlang's OTP 21

I find this error when compiling erlport dependency on a Phoenix project.

===> Compiling erlport
===> Compiling src/erlport.erl failed
src/erlport.erl:392: erlang:get_stacktrace/0: deprecated; use the new try/catch syntax for retrieving the stack backtrace

** (Mix) Could not compile dependency :erlport, "/Users/username/.mix/rebar3 bare compile --paths "/Users/username/project/path/_build/dev/lib/*/ebin"" command failed. You can recompile this dependency with "mix deps.compile erlport", update it with "mix deps.update erlport" or clean it with "mix deps.clean erlport"

My Elixir version

Erlang/OTP 21 [erts-10.0.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] [dtrace]

Elixir 1.6.6 (compiled with OTP 20)

Protocol attempts to write to closed fifo

In this code:

                try:
                    response = handler(*args)
                except:
                    response = self._handle_error(sys.exc_info())
    port.write(response)

if handler() attempts a port.write() which fails with EOFError (originally OSError(EPIPE)), the exception catch will craft a reponse for it which will cause another attempt to port.write() to the same, closed fifo.

Essentially, the EOFError() should not be caught by the try block

Enhancement request for monitoring erlport callers

We are using erlport to communicate with pools of Python processes in a production system. Each Python OS process has a 1-1 gen_server that utilizes erlport for bi-directional communication between the erlang VM and Python. The problem we have is the pooler library we are using does brutal_kill on the gen_server when a pool is shutdown leading to an untrappable exit of the gen_server. So we do not have an opportunity in our gen_server to terminate the port and we end up leaking Python processes. One way to resolve this problem is to enhance erlport to monitor its callers and call port_close whenever the last caller associated with the port has been shutdown. Here is a solution that I have tested in our environment.

$ git diff
diff --git a/src/erlport.erl b/src/erlport.erl
index ffa0670..afdf85c 100644
--- a/src/erlport.erl
+++ b/src/erlport.erl
@@ -122,9 +122,10 @@ init(Fun) when is_function(Fun, 0) ->
 %% @doc Synchronous event handler
 %% @hidden
 %%
-handle_call(Call={call, _M, _F, _A, Options}, From, State=#state{})
+handle_call(Call={call, _M, _F, _A, Options}, {Pid, _Ref} = From, State)
         when is_list(Options) ->
-    send_request(Call, From, Options, State);
+    NewState = monitor_caller(Pid, State),
+    send_request(Call, From, Options, NewState);
 handle_call(Request, From, State) ->
     Error = {unknown_call, ?MODULE, Request, From},
     {reply, Error, State}.
@@ -160,6 +161,21 @@ handle_info({'EXIT', Pid, {Id, Result}}, State=#state{calls=Calls}) ->
         error ->
             {noreply, State}
     end;
+handle_info({'DOWN', Ref, process, Pid, _Reason}, State=#state{port=Port, callers=Callers}) ->
+    case orddict:find(Pid, Callers) of
+        error ->
+            {noreply, State};
+        _ ->
+            erlang:demonitor(Ref),
+            Callers2 = orddict:erase(Pid, Callers),
+            case orddict:size(Callers2) of
+                0 ->
+                    port_close(Port),
+                    {stop, shutdown, State#state{callers=Callers2}};
+                _ ->
+                    {noreply, State#state{callers=Callers2}}
+            end
+    end;
 handle_info({erlport_timeout, {in, Id}}, State=#state{calls=Calls}) ->
     case orddict:find(Id, Calls) of
         {ok, {Pid, _Timer}} ->
@@ -410,3 +426,15 @@ incoming_call(Id, Module, Function, Args, _Context, State=#state{
             Calls2 = orddict:store(Id, Info, Calls),
             {noreply, State#state{calls=Calls2}}
     end.
+
+%%
+%% @doc Add monitor for caller
+%%
+monitor_caller(Pid, State=#state{callers = Callers}) ->
+    case orddict:find(Pid, Callers) of
+        error ->
+            Ref = erlang:monitor(process, Pid),
+            State#state{callers=orddict:store(Pid, Ref, Callers)};
+        _ ->
+            State
+    end.
diff --git a/src/erlport.hrl b/src/erlport.hrl
index d3eb01b..0d4bad7 100644
--- a/src/erlport.hrl
+++ b/src/erlport.hrl
@@ -40,7 +40,9 @@
     % orddict(): CallId -> {From::term(), Timer::reference() | undefined}
     sent = orddict:new() :: list(),
     % orddict(): CallId -> {Pid::pid(), Timer::reference()}
-    calls = orddict:new() :: list()
+    calls = orddict:new() :: list(),
+    % orddict(): CallerId -> Monitor::reference()
+    callers = orddict:new() :: list()
     }).

 -endif. % ERLPORT_HRL

For those who might find it helpful. Applicable to python3 only

screenshot from 2017-05-31 00-20-23

  • If we look closely to these tables -> columns for erlang binary() to python bytes() for [python3 only] vise versa.

  • This basically means that arguments of str() data type in erlang sent over to python functions will be converted to bytes() in python3.

  • So for python functions expecting arguments of str() data type, do not forget to convert the received arguments back to python string before using.

# gist ref
decoded_args = locals()
for arg_name, arg_value in locals().items():
if isinstance(arg_value, bytes):
decoded_args[arg_name] = arg_value.decode("utf-8")

Cast/Call from Python to erlang?

Looking at docs it shows to use:

from erlport.erlang import call

but in the erlport/erlang.py call is not even exposed its inside def MessageHandler(object):

Maybe I am doing something wrong or the documentation is outdated?

EDIT: I kind of hacked together a cast which is really not a cast but a send using:

from erlport.erlterms import Atom
from erlport.erlproto import Port

port = Port()
port.write((Atom('M'), fromerlang_pid, "hi"))

Error when call erlang function from python

I'm following this guid to play the python demo:
http://erlport.org/docs/python.html#call-erlang-functions-from-python

When I call python from erlang then got some error:

(sonic@node1)3> python:call(P, pids, pids, []).
18:47:56.046 [error] CRASH REPORT Process <0.260.0> with 0 neighbours exited with reason: {1,{ok,<0.260.0>}} in erlport:'-spawn_call/4-fun-0-'/4 line 249
18:47:56.048 [error] CRASH REPORT Process <0.261.0> with 0 neighbours exited with reason: {1,{ok,<0.261.0>}} in erlport:'-spawn_call/4-fun-0-'/4 line 249
[<0.260.0>,<0.261.0>]

looks like those error does not affect the results, but I'm no idea where were wrong.

anyone can help? thanks.

Incorrect work with decorators

When you use decorators for functions, responsible for handling messages, erlport doesn't invoke them when the message arrives:

def some_decorator(fn):
    def _inner(self, x):
        return fn(self, x + 1)
    return _inner

class SomeProtocol(Protocol):
    @some_decorator
    def handle_msg(self, x):
        return ...

Now, if you try to send a command {msg, X} from erlang, it will not be recognized.

importing erlport in Python3 yields syntax error

> pip3 install erlport
Collecting erlport
Installing collected packages: erlport
Successfully installed erlport-0.6
> python3
Python 3.5.2 (default, Nov 25 2016, 16:29:04) 
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import erlport
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.5/site-packages/erlport/__init__.py", line 33, in <module>
    from erlport.erlproto import Port, Protocol
  File "/usr/local/lib/python3.5/site-packages/erlport/erlproto.py", line 107
    except IOError, why:
                  ^
SyntaxError: invalid syntax

I noticed the current version of erlport is 0.9.8 but the one listed on pypi is 0.6. Is this correct? If not, can the python package on pypi be updated?

Tangentially, how does one go about installing the erlport python library from the source code?

system calls in Ruby script not working

I understand that if I'm going to be writing Elixir, I might as well use its method for calling system methods. But in the interest of reusing existing Ruby scripts, the first thing I tried after "hello world" is to make a
system call with ruby.

I'm following the tutorial here: Ruby code in Elixir project

I have this elixir file:

defmodule RubyElixir.RubyCall do
  use Export.Ruby
  def ruby_call do
    {:ok, ruby} = Ruby.start(
      ruby_lib: Path.expand("lib/ruby")
    )
    ruby
    |> Ruby.call("ruby", "ruby_v", [])
  end
end

and this ruby file:

def ruby_v(name)
  puts system "ruby -v"
end

With either system or backticks, I get this error:

iex(1)> RubyElixir.RubyCall.ruby_call
** (ErlangError) erlang error: {:ruby, :IOError, "unsupported STDOUT operation for ErlPort", ["-e:1:in `<main>'", "/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'", "/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'", "/home/max/Elixir/ruby_elixir/_build/dev/lib/erlport/priv/ruby1.9/erlport/cli.rb:94:in `<top (required)>'", "/home/max/Elixir/ruby_elixir/_build/dev/lib/erlport/priv/ruby1.9/erlport/cli.rb:41:in `main'", "/home/max/Elixir/ruby_elixir/_build/dev/lib/erlport/priv/ruby1.9/erlport/erlang.rb:138:in `start'", "/home/max/Elixir/ruby_elixir/_build/dev/lib/erlport/priv/ruby1.9/erlport/erlang.rb:194:in `_receive'", "/home/max/Elixir/ruby_elixir/_build/dev/lib/erlport/priv/ruby1.9/erlport/erlang.rb:234:in `call_with_error_handler'", "/home/max/Elixir/ruby_elixir/_build/dev/lib/erlport/priv/ruby1.9/erlport/erlang.rb:195:in `block in _receive'", "/home/max/Elixir/ruby_elixir/_build/dev/lib/erlport/priv/ruby1.9/erlport/erlang.rb:221:in `incoming_call'", "/home/max/Elixir/ruby_elixir/lib/ruby/ruby.rb:2:in `ruby_v'", "/home/max/Elixir/ruby_elixir/lib/ruby/ruby.rb:2:in `system'", "/home/max/Elixir/ruby_elixir/_build/dev/lib/erlport/priv/ruby1.9/erlport/stdio.rb:59:in `method_missing'"]}
    (erlport) src/erlport.erl:234: :erlport.call/3

windows path have spaces

Hi,
In windows's path have spaces, so open_port cannot work.

Can be solved in the following way:

Fullname = have_blank(filename:nativename(filename:absname(Filename))) % in erlport_options 252

have_spaces(FullName) ->
case string:str(FullName, " ") of
0 -> FullName;
_ -> """ ++ FullName ++ """
end.

Hope useful.

Confict between pandas and erlport?

I am passing data between erlang and python using erlport, following the example here:
http://erlport.org/docs/python.html

the python file I'm calling only contains the line:

import pandas as pd

I am getting the error:

    ** exception error: {python,'exceptions.AttributeError',
                                "'function' object has no attribute 'lower'",
                                [{<<"/anaconda/lib/python2.7/site-packages/pandas/core/format.py">>,
                                  1701,<<"detect_console_encoding">>,
                                  <<"if not encoding or 'ascii' in encoding.lower():  # try again for something bette"...>>},
                                 {<<"/anaconda/lib/python2.7/site-packages/pandas/core/config_init.py">>,
                                  234,<<"<module>">>,
                                  <<"cf.register_option('encoding', detect_console_encoding(), pc_encoding_doc,">>},
                                 {<<"/anaconda/lib/python2.7/site-packages/pandas/__init__.py">>,
                                  25,<<"<module>">>,<<"import pandas.core.config_init">>},
                                 {<<"/Documents/data-algorithms/Alg"...>>,
                                  3,<<"<module>">>,<<"import pandas as pd">>},
                                 {<<"/Documents/testki"...>>,
                                  237,<<"_incoming_call">>,
                                  <<"f = __import__(module, {}, {}, [objects[0]])">>},
                                 {<<"/Documents/te"...>>,
                                  245,<<"_call_with_error_handler">>,<<"function(*args)">>}]}
         in function  erlport:call/3 (src/erlport.erl, line 234)
         in call from algo_tester:start/0 (src/algo_tester.erl, line 27)

I can get rid of the error by commenting out the following two lines in /anaconda/lib/python2.7/site-packages/pandas/core/config_init.py:

    234        cf.register_option('encoding', detect_console_encoding(), pc_encoding_doc,
    235                            validator=is_text)

but then print doesn't work any longer.

Has anyone encountered this before?

Port._read_data() may read excess data

Hi.

I might be wrong as I've spent just several minutes looking into code.
But the code of Port._read_data() seems to have a problem. It may read excess data.
The better way to explain the problem is to show the patch that should resolve it:

--- erlproto.py 2011-04-17 16:21:42.000000000 +0400
+++ erlproto.new.py 2011-04-17 16:21:54.000000000 +0400
@@ -103,7 +103,7 @@
         data = ""
         while len(data) != length:
             try:
-                buf = os.read(self.in_d, length)
+                buf = os.read(self.in_d, length - len(data))
             except IOError, why:
                 if why.errno == errno.EPIPE:
                     raise EOFError()

and the rest of the function:

                data += nuf
        return data

As you can see, if we have read not enough data we would go once again into the loop.
But we will try to read again the whole chunk with length "length" while we should read the remain part "length - len(data)"

Ivan.

python:start(Name,Options) throws exception.

When attempting to start a named python client the following exception is thrown.
no function clause matching gen:where(Name)

It is possibly the fact that this library is not necessarily supported under erlang/OTP-20.

My version is:
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [kernel-poll:false]

Remove duplicated code

For python:
I think we can use six library, it can come as git submodule
For ruby:
maybe drop 1.8 support, cause it old, and maintenance will end on July 31, 2014.
maybe even drop 1.9, and support current 2.0 and 2.1 (I'm not a ruby guy, but I hope it will be one code version for both)

Actually I implemented #15 for myself, and wanted to submit PR, but found frustrating that there is almost the same code for python2 and python3.

I could try to make one code for both python2 and python3.
I could also try to do smth with ruby.

What do you think?

Port closed on erlport.cli, again

Running Erlport through Elixir, I was getting this error, and it was driving me nuts:

/usr/bin/python: No module named erlport.cli

** (ErlangError) erlang error: {:port_closed, {:code, 1}}

17:46:26.849 [error] GenServer #PID<0.128.0> terminating
** (stop) {:port_closed, {:code, 1}}
Last message: {#Port<0.5453>, {:exit_status, 1}}
State: {:state, :infinity, 0, #Port<0.5453>, [{1, {{#PID<0.126.0>, #Reference<0.0.5.24>}, :undefined}}], []}
    src/erlport.erl:234: :erlport.call/3

The way I resolved the issue was through:

pip uninstall erlport

Indeed, it seems that the erlport python module used internally is called "erlport", and so is the module used by external scripts, which caused this issue.

Perhaps consider renaming the internal python module?

NOTE: an issue about this seems to have been raised before here #6

Python: `cd` option problems.

Looks like cd option introduce some problems:

1> PyBaseDir = "/home/seriy/workspace/mediamon_crawl/priv/py_trash_filter",
1> Virtualenv = PyBaseDir ++ "/pyenv",
1> Python = Virtualenv ++ "/bin/python2.7".
2> python:start([{env, [{"VIRTUAL_ENV", Virtualenv}]},
                 {python, Python},
                 {python_path, [PyBaseDir]}]).
{ok,<0.355.0>}
3> python:start([{env, [{"VIRTUAL_ENV", Virtualenv}]},
                 {python, Python},
                 {python_path, [PyBaseDir]},
                 {cd, PyBaseDir}]).
{ok,<0.357.0>}
/home/seriy/workspace/mediamon_crawl/priv/py_trash_filter/pyenv/bin/python2.7: No module named erlport

Looks like this is because https://github.com/hdima/erlport/blob/1.0.0alpha/src/python_options.erl#L119 generate relative path. Maybe wrap it with filemane:absname/1?

Using erlport/ruby with Elixir v1.1.0 seems to have an issue, looking to understand the cause.

I made a repo demonstrating example usage with Python in Elixir here: (https://github.com/arthurcolle/elixir-snake)

When I redownload it, run mix deps.get, then iex -S mix, in the interpreter, running this should work:

just like how
iex(2)> {:ok, python} = :python.start() returns:
{:ok, #PID<0.90.0>}
the ruby version should also work, however running this:
iex(2)> {:ok, ruby} = :ruby.start()
{:ok, #PID<0.95.0>}
iex(3)> /Users/arthur/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in require': cannot load such file -- erlport/cli (LoadError) from /Users/arthur/.rubies/ruby-2.2.2/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:inrequire'
from -e:1:in `

'

23:42:43.046 [error] GenServer #PID<0.95.0> terminating
Last message: {#Port<0.3940>, {:exit_status, 1}}
State: {:state, :infinity, 0, #Port<0.3940>, [], []}
** (stop) {:port_closed, {:code, 1}}

What exactly is the problem? Is there a gem that I need to download and install in order to make it work? I couldn't find this in the docs, but I'd appreciate any pointers. Thanks!

Insensible Python3 Type Mapping

While trying to call boto.s3.connection S3Connection.get_bucket method in Python3, realised that there is no way to pass in a str() in Python3.

Erlang Char lists (string) become lists in Python 3. Erlang binary becomes bytes in Python3. But using bytes.decode in python3 results in a char list being returned back to the Erlang VM, instead of an opaque object that represents a python3 str(). Thus there is no way to pass in a str object to a method call.

erlport.cli

I try:
{ok, P} = python:start().

Error:
/usr/bin/python: No module named erlport.cli

Where is erlport.cli ?
Tnx.

Should not convert negative integer in ruby array as erlang string

I use custom type for parsing ruby ast.
I found that negative integer array of ruby is encoded as erlang string of incorrect value.

def single_neg                                                                  
  [-1]                                                                          
end                                                                             

def two_neg                                                                     
  [-1,-2]                                                                       
end                                                                             

def single_pos                                                                  
  [1]                                                                           
end                                                                             

def two_pos                                                                     
  [1,2]                                                                         
end                                                                             

calling these functions generate incorrect value

1> {ok, R} = ruby:start().
{ok,<0.35.0>}
2> ruby:call(R, './int_ary.rb', single_neg, []).  
"ÿ"
3> ruby:call(R, './int_ary.rb', two_neg, []).     
"ÿþ"
4> ruby:call(R, './int_ary.rb', single_pos, []).  
[1]
5> ruby:call(R, './int_ary.rb', two_pos, []).     
[1,2]

the real problem is that it's not a char with proper value

6> Tn = ruby:call(R, './int_ary.rb', two_neg, []).  
"ÿþ"
9> lists:nth(1,Tn).
255
10> lists:nth(2,Tn).
254

which should be -1 and -2, not 255 and 254.

problem with zip file in PYTHONPATH

Hi,

When I try to start erlport I get the following:

3> {ok, P} = python:start().
** exception error: no match of right hand side value
{error,{not_dir,"C:\WINDOWS\system32\python25.zip"}}

This is inconvenient. I am not a python expert, but I think it is not unusual to have zip files in PYTHONPATH.

Regards,
Willem

{error,function_clause} hides real errors

TypeError is a common error and the exception handling in erlproto.py that returns {error, function_clause} will hide errors that occur in the handler function. Short of explicitly checking arg count (IMO unnecessary), I think it would be preferable to let the exception propagate.

Cannot Pickle built-in Python objects

Since erlport cannot do variable assignments without pickling to erlang, I had met with the following problem:
http://stackoverflow.com/questions/7107409/why-does-pickle-protocol-2-let-me-serialise-an-open-file-object

iex(33)> fp = :python.call(pid, :'__builtin__', :'open', ["test.log", "r+"])
iex(34)> :python.call(pid, :'__builtin__', :'repr', [fp])
"<closed file '<uninitialized file>', mode '<uninitialized file>' at 0x106003ae0>"

It is suggested to switch from pickle to dill (https://github.com/uqfoundation/dill).
Dill can pickle the following standard types::

none, type, bool, int, long, float, complex, str, unicode,
tuple, list, dict, file, buffer, builtin,
both old and new style classes,
instances of old and new style classes,
set, frozenset, array, functions, exceptions
Dill can also pickle more 'exotic' standard types::

functions with yields, nested functions, lambdas
cell, method, unboundmethod, module, code, methodwrapper,
dictproxy, methoddescriptor, getsetdescriptor, memberdescriptor,
wrapperdescriptor, xrange, slice,
notimplemented, ellipsis, quit

rebar3 compile doesn't run the makefile

How did I encounter the issue?

I used erlport as a git dependency in the rebar.config of my erlang project.
Running my project throws an error when erlport tries to open python3.
Turns out python3 only works after the erlport project has been built with the makefile.

Temporary fix

For the moment I have to enter the directory of erlport (which is a dependency of my project) and manually run 'make'.
Alternatively I could script it in my root project to build the dependency, but this solution smells.

Suggestion

Building erlport can be automatized by rebar3, by adding a pre-compile hook in the rebar3.config.
This way all rebar3 projects that use erlport as a dependency will build it automatically after fetching it from git.

Missing Python API

The described Python API is not available:

>>> import erlport.erlang
>>> erlport.erlang.call
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'call'

Trouble building from source with Erlang 17.3

Our sysadmin tried to install erlport. We're running RH Rel 6 (Erlang 17.3-2.el6 rpm). Since binary releases were only available for versions up to 16, he tried to build from source.

He reports:
am getting quite a few build errors terminating with:

./release bin
./release: line 14: erlport-Erlang/OTP 17 [erts-6.2] [source-5c974be] 
[64-bit] [smp:4:4] [async-threads:10] [hipe] 
[kernel-poll:false]-0.9.8.tar.gz: No such file or directory
make: *** [release] Error 1

An issue running this with erlang v17 perhaps? 

Is there a version 17 binary release somewhere?

Thanks!

-Mark

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.