Why can the following environment module not be loaded? - environment

I get an error loading environment modules (4.2.4) I do not understand. With three modules A, B and C where B depends on A and C and C depends only on A:
A
#%Module1.0
B
#%Module1.0
module load A C
C
#%Module1.0
module load A
it is not possible to load the modules in the following manner:
module load A B
The error that is printed to stdout is:
Error: B cannot be loaded due to missing prereq.
HINT: the following modules must be loaded first: C
A module load A C B is working.
Is this a bug of the module environment or am I missing something?

You clearly hit a bug. module load A B should work as you expect.
I have reported it to the project on GitHub
As a work-around, you could also pass the --auto command-line switch:
$ module load --auto A B
Loading B
Loading requirement: C
$ module list
Currently Loaded Modulefiles:
1) A 2) C 3) B
Another work-around is to write B modulefile with 2 separate module load commands:
#%Module1.0
module load A
module load C
UPDATE: Environment Modules 4.2.5 is now released and includes a fix for this issue. So module load A C command in B modulefile correctly loads A and C modulefiles.

Related

Python cyclic import unexpected behavior

I have discovered something unexpected when playing with cyclic imports. I have two files in the same directory:
a.py
import b
print("hello from a")
b.py
import a
print("hello from b")
Running either python3 a.py and python3 b.py does not result in a cyclic import related error. I know that the first imported module is imported under the name __main__, but I still do not understand this behavior. For example, running python3 a.py or python -m a produces the following output:
hi from a
hi from b
hi from a
Looking at the output of print(sys.modules.keys()), I can see that both modules are somehow already imported when checking it, even when importing the sys module as the first thing in one of the modules.
I did not use sys.modules properly before answering my own question.
This does not happen if neither of the cyclic imported modules is the __main__ module. My Python version is Python 3.6.3 on Ubuntu 17.10.
It still happens, but there is a visible error only if there is actually something you use from one of the cyclically imported modules.
See my own answer for clarifications.
The answer to my question
I have discovered the answer. I will try to sketch an explanation:
Executing python3 a.py imports the module in file a.py as __main__:
import b in module __main__:
import a in module b -> Imports the module in file a.py as a
import b in module a -> Nothing happens, already imported that module
print('hello from a') in a.py (executing module a)
import a in module b finished
print('hello from b') in b.py (executing module b)
import b in module __main__ finished
print('hello from a') in a.py(executing module __main__)
The problem is that there is no cyclic import error per se. A module is imported only once, and after that, other imports of the same module can be seen as no-ops.
This operation can be seen as adding a key to the sys.modules dictionary corresponding to the name of the imported module and then setting attributes on the module object associated with that key as it gets executed. So if the key is already present in the dictionary (on a second import of the same module), nothing happens on the second import. The already imported above means already present in the sys.modules dictionary. This reflects the procedural nature of Python (being originally implemented in C) and the fact that anything in Python is an object.
The lurking problem
In order to show the fact that the problem associated with cyclic imports is still present, let's add a function to module b and try to use it from module a.
a.py
import b
b.f()
b.py
import a
def f():
print('hello from b.f()')
Executing now python a.py imports the module in file a.py as __main__:
import b in module __main__:
import a in module b -> Imports the module in file a.py as a
import b in module a -> Nothing happens, already imported that module
b.f() -> AttributeError: module 'b' has no attribute 'f'
Note: The line b.f() can be further simplified to b.f and the error will still occur. This is because b.f() first accesses the attribute f of module object b, which happens to be a function object, and then tries to call it. I wanted to point out again the object oriented nature of Python.
The from ... import ... statement
It is interesting to mention that using the from ... import ... form gives another error, even though the reason is the same:
a.py
from b import f
f()
b.py
import a
def f():
printf('hello from b.f()')
Executing python a.py imports the module in file a.py as __main__:
from b import f in module __main__ actually imports the whole module (adds it to sys.modules and executes its body), but binds only the name f in the current module namespace:
import a in module b -> Imports the module in file a.py as a
from b import f in module a -> ImportError: cannot import name f (because the first execution of from b import f did not get to see the definition of the function object f in module b)
In this last case, the from ... import ... itself fails with an error because the interpreter knows earlier in time that you are trying to access something in that module which does not exist. Compare it to the first AttributeError, where the program did not see any problem until it tried to access attribute f (in the expression b.f).
The double execution problem of the code in the main module
When importing the module in the file used to start the program (imported as __main__ first) from another module, the code in that module gets executed twice and any side effects in that module execution will happen twice too. This is why it is not recommended to import the main module of the program again in other modules.
Using sys.modules to confirm my conclusions above
I will show how checking the contents of sys.modules can clarify this problem:
a.py
import sys
assert '__main__' in sys.modules.keys()
print(f'{__name__}:')
print('\ta imported:', 'a' in sys.modules.keys())
print('\tb imported:', 'b' in sys.modules.keys())
import b
b.f()
b.py
import sys
assert '__main__' in sys.modules.keys()
print(f'{__name__}:')
print('\ta imported:', 'a' in sys.modules.keys())
print('\tb imported:', 'b' in sys.modules.keys())
import a
assert False # Control flow never gets here
def f():
print('hi from b.f()')
The output of python3 a.py:
__main__:
a imported: False
b imported: False
b:
a imported: False
b imported: True
a:
a imported: True
b imported: True
Traceback (most recent call last):
File "a.py", line 8, in <module>
import b
File "/home/andrei/PycharmProjects/untitled/b.py", line 8, in <module>
import a
File "/home/andrei/PycharmProjects/untitled/a.py", line 10, in <module>
b.f()
AttributeError: module 'b' has no attribute 'f'

lua lxp The specified module could not be found

I'm putting together an application that uses the moon soap, but when you run it reports the following error :
C:\Lua\5.1\lua.exe: error loading module 'lxp' from file 'C:\Lua\5.1\clibs\lxp.dll':
The specified module could not be found.
How do I fix this ?
This is not a "file not found" error. Note that the message stated that it tried to load the module "lxp" from a file ('C:\Lua\5.1\clibs\lxp.dll') but it didn't work. Maybe the file doesn't have a luaopen_lxp C function (which might be called by loadlib)... Or maybe you are not loading it with require...

Defining Modules VS.NET vs F# Interactive

I have written this code which compiles and works perfectly in VS.NET 2010
module ConfigHandler
open System
open System.Xml
open System.Configuration
let GetConnectionString (key : string) =
ConfigurationManager.ConnectionStrings.Item(key).ConnectionString
however when I do a control + A and Alt + Enter to send this to FSI I get an error
ConfigHandler.fs(2,1): error FS0010: Unexpected start of structured construct in definition. Expected '=' or other token.
OK.
So I change my code to
module ConfigHandler =
open System
open System.Xml
open System.Configuration
let GetConnectionString (key : string) =
ConfigurationManager.ConnectionStrings.Item(key).ConnectionString
Now Control + A, Alt + Enter is successful and I FSI nicely tells me
module ConfigHandler = begin
val GetConnectionString : string -> string
end
However now If I try to compile my code in VS.NET 2010, I get an error message
Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'
How can I have both? Ability to compile in VS.NET and the ability to send modules to FSI?
There is a tiny -- but crucial -- difference between your two snippets of code which is to blame here.
F# has two ways to declare a module. The first, a "top-level module", is declared like this:
module MyModule
// ... code goes here
The other way to declare a module is as a "local module", like so:
module MyModule =
// ... code goes here
The main differences between the "top-level" and "local" declarations are that the local declaration is followed by an = sign and the code within a "local" module must be indented.
The reason you get the ConfigHandler.fs(2,1): error FS0010: Unexpected start of structured construct in definition. Expected '=' or other token. message for the first snippet is that you can't declare top-level modules in fsi.
When you added the = sign to your module definition, it changed from a top-level module to a local module. From there, you got the error Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule' because local modules must be nested within a top-level module or a namespace. fsi doesn't allow you to define namespaces (or top-level modules), so if you want to copy-paste the entire file into fsi the only way it'll work is if you use the compilation directives as #pad mentioned. Otherwise, you can simply copy-paste the local module definitions (without the containing namespace) into fsi and they should work as expected.
Reference:
Modules (F#) on MSDN
The common solution is to keep the first example and create a fsx file which references the module:
#load "ConfigHandler.fs"
You have advantage of loading multiple modules and writing plumbing code for experiment.
If you really want to load ConfigHandler.fs directly to F# Interactive, you can use INTERACTIVE symbol and compiler directives:
#if INTERACTIVE
#else
module ConfigHandler
#endif
which works for both fsi and fsc.

Error while creating a F# Library

I created a new F# library with say the following expressions:
module Module1
let x = 2 + 2
When trying to run this, I get an error
Unexpected start of structured construct in definition. Expected '=' or other token.
When you say "run", do you mean select all -> ALT + ENTER to send to FSI? If so, I think that is your issue. FSI doesn't handle file-level module declarations. You need to either not select module Module1 when you send it to FSI, or change it to a module expression:
module Module1 =
let x = 2 + 2

Is there any way to force load a module when it is opened through FSI?

If I compile the following module into a dll
namespace MyNs
module SomeModule =
do printfn "module loading"
let x = 23
then reference the dll in FSI and execute the command open MyNs.SomeModule "module loading" does not print immediately. It only prints when I access x which causes all the top level let and do bindings to execute (normal behavior I know in the .NET world). Is there any way, perhaps via an attribute on the module, I can indicate that module should load immediately upon opening in FSI?
Opening a module never does anything at runtime. It just puts all the symbols in the opened namespace in scope for unqualified access below the open statement.
Section 12.5 of the language spec is what you want to read - this details when the static initialization of a module will run.
Given that, the only time when this initialization is run automatically, as far as I know, is for last module in an exe.
I.e. I don't think there is a direct way to accomplish what you want.
If you have reflective access to the module:
ModuleType.TypeInitializer.Invoke(null, null)
will invoke the static initialization.
You can add the AutoOpen attribute to the module
[<AutoOpen>]
module SomeModule =
do printfn "module loading"
let x = 23
However this will only print the module loading message when you reference x.
Not sure if you found the solution to your problem but in my case I wanted to start an agent when my website was starting and it was indeed starting twice like you mentioned.
What I did was set a method let start() = inside the module and invoke the method using a static do xxx.start() from my main Site type.
Found that by reading the language spec Kurt linked.

Resources