I am very new to Lua, so pardon for the retarded question.
Following this tutorial I am trying to import DeepMind dqn into an iTorch notebook.
I have cloned this repo that contains a folder called dqn where the source code lives.
I have added the path to the dqn folder
package.path = package.path .. ";/path/to/dqn/?.lua"
When I try to do
require 'dqn'
I obtain an (expected) error, since there is no file called dqn.lua in the folder. The source code of such module is, in fact, contained in the file NeuralQLearner.lua.
I have seen the documentation that hints at the problem between file and package name.
So my question is: how can I import this module correctly? How can I let Lua know that dqn it should actually look for NeuralQLearner.lua (without hardcoding into the path I guess)?
The trick is in:
if not dqn then
require 'initenv'
end
put in every file. The initenv file will then define what dqn is supposed to mean. Once the path to initenv is package.path, this seems a nice trick to overcome the limitation.
Related
Let's say I have a directory like this
In main.py I have the code from main_package import func but I get an error saying
test/main_package/func.py", line 1, in <module>
from sub_package.aa import aaf1
ModuleNotFoundError: No module named 'sub_package'
The line from sub_pacakage.aa import aaf1 in main_package/func.py is causing the error. I can switch that line to an asbolute path (from main_package.sub_pacakage.aa import aaf1) and it works fine.
However, I want to not change the relative path to an absolute path.
I am assuming I have to modify main_package/__init__.py to achieve this but I am not sure how. How do I go about this?
I've tried adding from . import sub_package to main_package/__init__.py but it doesn't seem to be working.
The issue with absolute Python imports is that they are actually relative to any path defined in sys.path and also to your current working directory.
Thus, to make an import like from sub_package.aa work, you need to ensure that the parent folder of "sub_package" is in sys.path or is your current working directory.
The same goes for from main_package.sub_package.aa. You need to make sure that the parent folder of main_package is in sys.path or is your current working directory. So it makes a different how and from which directory you execute your Python code. You usually need to "cd" to the right directory first.
I've had similar problems in the past and thus I've created an experimental, new import library: ultraimport
It gives you more control over your import and lets you do file system based imports and therefore real relative imports. You could then write your func.py like this:
import ultraimport
# Given that aaf1 is defined in aa.py from your sub package
aaf1 = ultraimport('__dir__/subpackage/aa.py', 'aaf1')
This will always work, no matter what is your current working directory, what is your sys.path or how you run your code.
I have the most basic of question that should be easy but proving to be a pain. I have a f# FSX file and would like to include Deedle.
I ran the install package and it put it in C:\Users\myName.nuget\packages
Under this directory, the deedle.fsx is in deedle\2.0.4
Now, some of the documentation I have read instructs to do this at the top of the FSX file:
"#I "../../packages/Deedle"
"#load "Deedle.fsx"
Issue#1. That relative path for #I does not work, so I use an explicit path. That resolves that issue.
Issue#2. I cannot get the load statement to find the deedle.fsx file. It appends a bin/net45 to the path.
Therefore, the question is is there a trick I am missing in using this library and how I am referencing it for use?
Thx,
Marc.
try this in your fsx file
#r #"C:\Users\myName\.nuget\packages\deedle\2.0.4\lib\net45\deedle.dll"
change myName to your username.
I'm trying to repackage into a Docker container some Lua library that is made of the main module and some helper modules. The helper modules are kept inside a subfolder of the library so that imports from the main file are done as
require 'helpers/SomeHelper'
The problem is: because of the way I want the Docker container to work, it would be extremely helpful if I can invoke this library from a different working folder. That is, my call to the main program would be something like
th /app/main.lua
regardless of the actual working directory I'm standing. Unfortunately, relative imports seem to fail when the working directory is different from the directory where the main file is located.
Is there any way I can configure LUA_PATH or any other mechanism to make these imports work correctly? Note that changing the code of the library itself would be a poor solution, as it wasn't developed by me and I would like to be able to update it to newer versions easily.
If you don't care about the working directory, you can just load lfs / LuaFileSytem and use lfs.chdir( src_dir ) to change to the source directory (potentially saving the current working directory with lfs.currentdir( ) first.)
You can also extend the search path of Lua so that it will search those extra directories. The search is driven by package.searchpath. To add a directory /foo/bar/ to the search in a way that supports all normally supported library layouts, add
/foo/bar/?.lua;/foo/bar/?/init.lua to package.path
/foo/bar/?.so (or .dylib or .dll on other OSen) to package.cpath
You can use several ways to extend the path.
One option that works well is to set the LUA_PATH / LUA_CPATH environment variables. (A ;; sequence in one of them will expand to the full default path.) This can be done from .profile or other setup scripts via an earlier export LUA_PATH="..." or (if started from a wrapper script) inline by setting variables just for that call LUA_PATH="..." lua /foo/bar.lua. (Note that if you export this variable in too broad a scope, other Lua scripts will also get their path extended and may find potentially incompatible Lua libraries.)
(You can also manually modify package.(c)path from LUA_INIT. That way, you won't be able to independently disable LUA_INIT or LUA_PATH, but you can use all of Lua to generate the path dynamically.)
A third option (this may be best in your specific case) is to put the extension of package.path at the top of your main script, as in
do
local dir = (arg[0]:match "^(.*)/$")
if dir then -- else cwd is . which works by default
package.path = dir.."/?.lua;"..dir.."/?/init.lua;"..package.path
package.cpath = dir.."/?.so;"..package.cpath
end
end
-- rest of your program goes here
When running a script with the Lua interpreter, arg[0] is the script. So this extends the path to include the program's directory no matter where it is located, and it will only affect the search path of this particular script / program.
You should not forget about that not all modules are loaded from FS directly.
E.g. to improve perfomance it is possible read/compile file to memory and then
use preload table to provide way to load module from memory.
Basic example
--- preload code. It can be done by host application.
local FooUtils = function()
return {
print = function(...)
print("foo", ...)
end
}
end
local Foo = function()
local Utils = require "foo.utils"
return {
foo = function()
Utils.print"hello"
end
}
end
package.preload['foo.utils'] = FooUtils
package.preload['foo'] = Foo
--- main application
require "foo".foo()
In this example assume that FooUtils and Foo just example of compiled modules.
E.g. it can be like FooUtils = loadstring('path/to/utils.lua) and it can be done
even in separate Lua state and then used in any other.
It is important to remember that Foo module have no idea about how host application does lookup of foo.utils.
So there no standart way to provide original file path or relevant paths.
So if you write some module wich relays on relative paths then this module
may be not working in some environments.
So I just suggest use full namespace like require 'foo.utils' instead of require 'utils'
So in lua, i want to import a module.
I want to have my "polygon" lib in a subfolder, so i reference it like this
local polygon = require('polygon.polygon')
however, it needs another module called 'delaunay', it cannot find it as it checks the main folder
Is there anyway short of editing my library, to get this to work? (some kind of ability to add search paths?)
Thanks
To know where to look for modules, Lua's require uses the variables package.path (.lua) and package.cpath (.so/.dll). You can change them in your program to look in the directory you have it in. For consistency's sake, you can look at their contents to know which OS-specific separator to use. For example:
local sep = package.path:find("\\") and "\\" or "/"
package.path = package.path .. ";." .. sep .. "polygon" .. sep .. "?.lua"
This would include ./polygon/?.lua into the search path, and a call to require "delaunay" would therefore have the require function look for ./polygon/delaunay.lua in addition to existing paths. Bear in mind that in require strings, . denotes a separator as far as file searching is concerned, so calling require "polygon.delaunay" in this scenario will mean searching for ./polygon/polygon/delaunay.lua.
From what I understand of your question, changing the package.path variable to include the path to where your delaunay library is stored would solve your issue, although to give a specific solution more information about your project and directory structure is required.
All what loaded into package.loaded can be load with require() because require() looks first in package.loaded...
-- Lua 5.3 ( lua -i )
> package.loaded.code=load(code.dump)()
> test=require('code')
> test
function: 0x565cb820
So you can use load() or loadfile('/path/to/your_code.lua') to do this. Another nice feature of this method is to load dumped code...
> package.loaded.shell=loadfile('shell.bin')
> shell=require('shell')
> shell('cat shell.bin')
uaS�
�
xV(w#F#�d�#��F�#G���d#��F�#G���d#&�typestringoexecute
/bin/bash>
In any way, it appears that you will have to deal with the subfolders explicitly.
As in, either the module polygon will have to import delaunay as polygon.delaunay.
Or module names will have to be appended to package.path so that lua could search through subfolders for filenames:
package.path=package.path..";./polygon/?.lua"
More info is here.
It is pointed out in comments, you'd probably want to ensure that path concatenation happens only once.
Also, one should be wary of name shadowing.
Finally, while we are at stirring up the past, a pretty nifty trick to solve the issue was proposed here five years before the question.
usually when I have a question about something remotely software related I find that someone else has already asked the very same thing, and gotten good answers that works for me too.
This time, though, I've failed to find an answer to my predicament.
Here we go:
I'm currently trying to move up my Lua-programming a notch or three and want to use modules. So, I've got a structure like this:
main.lua
foo/bar.lua
Now, in main.lua I do
require("foo.bar")
which fails,
main.lua:1 module 'foo.bar' not found:
no field package.preload['foo.bar']
no file 'foo.bar.lua'
no file 'foo.bar.lua'
no file 'foo.lua'
Ok, something might be wrong with my package.path so I use package.searchpath("foo.bar", package.path) to see what I', doing wrong.
The problem is that package.searchpath resolves foo.bar to foo/bar.lua which is exactly right.
As I've understood it, package.searchpath tries to find the module in the same way as require, but there seems to be som glitch in my case.
What strikes me as odd is the repetition of the no file 'foo.bar.lua' in the error output
Have I misunderstood the use of require?
I'm using LuaJIT-2.0.0 to run my chunks
Update:
I'm using LuaJIT-2.0.0 to run my chunks <- This was the reason for my problem, stock Lua-5.2.2 behaves as expected
package.path = debug.getinfo(1,"S").source:match[[^#?(.*[\/])[^\/]-$]] .."?.lua;".. package.path
require("foo.bar")
This line causes require to look in the same directory as the
current file when asked to load other files. If you want it to instead
search a directory relative to the current directory, insert the
relative path between " and ?.lua
Here is part of require description:
[...] Otherwise require searches for a Lua loader using the path stored in
package.path. If that also fails, it searches for a C loader using the
path stored in package.cpath. If that also fails, it tries an
all-in-one loader (see package.loaders).
Default path for package.path is always the .exe that executes specified script.