I am creating a type which holds a procedure as one of its fields. When I attempt to compile the file, it provides me with the error 'CommandC' is not a concrete type.
The problematic snippet is seen below.
type
CommandC = object
tocall: proc (info: CommandC, vrs: SharedTable)
arguments: seq[seq[string]]
subcommands: seq[CommandC]
CommandP = object
cat: string
tocall: proc (info: CommandC, vrs: SharedTable) # This line raises an error during compilation
arguments: seq[string]
textdata: string
I am new to Nim [transitioning from Python for larger projects] and for the life of me cannot figure out what this actually means, or how to fix it. This is likely plain old incompetence on my part.
[I am also new to using Stack Overflow and so if my question is not up to standards then that's my bad and I apologize]
I guess you have found it yourself already. But in case that it was not that obvious, you may understand that Nim is not Python, but a statically typed, compiled language. An unspecified data type like SharedTable can not exist. A table (map) is a mapping from one type to another type, so something like SharedTable[string, int] makes more sense, and the code below compiles for me:
import std/sharedtables
type
CommandC = object
tocall: proc (info: CommandC, vrs: SharedTable[string, int])
arguments: seq[seq[string]]
subcommands: seq[CommandC]
CommandP = object
cat: string
tocall: proc (info: CommandC, vrs: SharedTable[string, int]) # This line raises an error during compilation
arguments: seq[string]
textdata: string
I'm trying to write a script in which I need to get the terminal size in order to adjust the output text width appropriately. I use this lines:
import os
x = os.get_terminal_size().lines
which results in getting this error:
ValueError: bad file descriptor
What's wrong with the code?
Try this:
import sys
import os
try:
cols,rows = os.get_terminal_size(0)
except OSError:
cols,rows = os.get_terminal_size(1)
sys.stdout.write('cols:{} \n rows:{} \n'.format(cols,rows))
Check out this page you can find multiple example with error handling
File "C:\Users\Administrator\Documents\Mibot\oops\blinkserv.py", line 82, in __init__
self.serv = socket(AF_INET,SOCK_STREAM)
TypeError: 'module' object is not callable
Why am I getting this error?
I'm confused.
How can I solve this error?
socket is a module, containing the class socket.
You need to do socket.socket(...) or from socket import socket:
>>> import socket
>>> socket
<module 'socket' from 'C:\Python27\lib\socket.pyc'>
>>> socket.socket
<class 'socket._socketobject'>
>>>
>>> from socket import socket
>>> socket
<class 'socket._socketobject'>
This is what the error message means:
It says module object is not callable, because your code is calling a module object. A module object is the type of thing you get when you import a module. What you were trying to do is to call a class object within the module object that happens to have the same name as the module that contains it.
Here is a way to logically break down this sort of error:
"module object is not callable. Python is telling me my code trying to call something that cannot be called. What is my code trying to call?"
"The code is trying to call on socket. That should be callable! Is the variable socket is what I think it is?`
I should print out what socket is and check print(socket)
Assume that the content of YourClass.py is:
class YourClass:
# ......
If you use:
from YourClassParentDir import YourClass # means YourClass.py
In this way, you will get TypeError: 'module' object is not callable if you then tried to call YourClass().
But, if you use:
from YourClassParentDir.YourClass import YourClass # means Class YourClass
or use YourClass.YourClass(), it works.
Add to the main __init__.py in YourClassParentDir, e.g.:
from .YourClass import YourClass
Then, you will have an instance of your class ready when you import it into another script:
from YourClassParentDir import YourClass
Short answer: You are calling a file/directory as a function instead of real function
Read on:
This kind of error happens when you import module thinking it as function and call it.
So in python module is a .py file. Packages(directories) can also be considered as modules.
Let's say I have a create.py file. In that file I have a function like this:
#inside create.py
def create():
pass
Now, in another code file if I do like this:
#inside main.py file
import create
create() #here create refers to create.py , so create.create() would work here
It gives this error as am calling the create.py file as a function.
so I gotta do this:
from create import create
create() #now it works.
Here is another gotcha, that took me awhile to see even after reading these posts. I was setting up a script to call my python bin scripts. I was getting the module not callable too.
My zig was that I was doing the following:
from mypackage.bin import myscript
...
myscript(...)
when my zag needed to do the following:
from mypackage.bin.myscript import myscript
...
myscript(...)
In summary, double check your package and module nesting.
What I am trying to do is have a scripts directory that does not have the *.py extension, and still have the 'bin' modules to be in mypackage/bin and these have my *.py extension. I am new to packaging, and trying to follow the standards as I am interpreting them. So, I have at the setup root:
setup.py
scripts/
script1
mypackage/
bin/
script1.py
subpackage1/
subpackage_etc/
If this is not compliant with standard, please let me know.
It seems like what you've done is imported the socket module as import socket. Therefore socket is the module. You either need to change that line to self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM), as well as every other use of the socket module, or change the import statement to from socket import socket.
Or you've got an import socket after your from socket import *:
>>> from socket import *
>>> serv = socket(AF_INET,SOCK_STREAM)
>>> import socket
>>> serv = socket(AF_INET,SOCK_STREAM)
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: 'module' object is not callable
I know this thread is a year old, but the real problem is in your working directory.
I believe that the working directory is C:\Users\Administrator\Documents\Mibot\oops\. Please check for the file named socket.py in this directory. Once you find it, rename or move it. When you import socket, socket.py from the current directory is used instead of the socket.py from Python's directory. Hope this helped. :)
Note: Never use the file names from Python's directory to save your program's file name; it will conflict with your program(s).
When configuring an console_scripts entrypoint in setup.py I found this issue existed when the endpoint was a module or package rather than a function within the module.
Traceback (most recent call last):
File "/Users/ubuntu/.virtualenvs/virtualenv/bin/mycli", line 11, in <module>
load_entry_point('my-package', 'console_scripts', 'mycli')()
TypeError: 'module' object is not callable
For example
from setuptools import setup
setup (
# ...
entry_points = {
'console_scripts': [mycli=package.module.submodule]
},
# ...
)
Should have been
from setuptools import setup
setup (
# ...
entry_points = {
'console_scripts': [mycli=package.module.submodule:main]
},
# ...
)
So that it would refer to a callable function rather than the module itself. It seems to make no difference if the module has a if __name__ == '__main__': block. This will not make the module callable.
I faced the same problem. then I tried not using
from YourClass import YourClass
I just copied the whole code of YourClass.py and run it on the main code (or current code).it solved the error
you are using the name of a module instead of the name of the class
use
import socket
and then
socket.socket(...)
its a weird thing with the module, but you can also use something like
import socket as sock
and then use
sock.socket(...)
I guess you have overridden the builtin function/variable or something else "module" by setting the global variable "module". just print the module see whats in it.
Here's a possible extra edge case that I stumbled upon and was puzzled by for a while, hope it helps someone:
In some_module/a.py:
def a():
pass
In some_module/b.py:
from . import a
def b():
a()
In some_module/__init__.py:
from .b import b
from .a import a
main.py:
from some_module import b
b()
Then because when main.py loads b, it goes via __init__.py which tries to load b.py before a.py. This means when b.py tries to load a it gets the module rather than the function - meaning you'll get the error message module object is not callable
The solution here is to swap the order in some_module/__init__.py:
from .a import a
from .b import b
Or, if this would create a circular dependency, change your file names to not match the functions, and load directly from the files rather than relying on __init__.py
I got the same error below:
TypeError: 'module' object is not callable
When calling time() to print as shown below:
import time
print(time()) # Here
So, I called time.time() as shown below:
import time
print(time.time()) # Here
Or, I imported time from time as shown below:
from time import time # Here
print(time())
Then, the error was solved:
1671301094.5742612
I had this error when I was trying to use optuna (a library for hyperparameter tuning) with LightGBM. After an hour struggle I realized that I was importing class directly and that was creating an issue.
import lightgbm as lgb
def LGB_Objective(trial):
parameters = {
'objective_type': 'regression',
'max_depth': trial.suggest_int('max_depth', 10, 60),
'boosting': trial.suggest_categorical('boosting', ['gbdt', 'rf', 'dart']),
'data_sample_strategy': 'bagging',
'num_iterations': trial.suggest_int('num_iterations', 50, 250),
'learning_rate': trial.suggest_float('learning_rate', 0.01, 1.0),
'reg_alpha': trial.suggest_float('reg_alpha', 0.01, 1.0),
'reg_lambda': trial.suggest_float('reg_lambda', 0.01, 1.0)
}
'''.....LightGBM model....'''
model_lgb = lgb(**parameters)
model_lgb.fit(x_train, y_train)
y_pred = model_lgb.predict(x_test)
return mse(y_test, y_pred, squared=True)
study_lgb = optuna.create_study(direction='minimize', study_name='lgb_regression')
study_lgb.optimize(LGB_Objective, n_trials=200)
Here, the line model_lgb = lgb(**parameters) was trying to call the cLass itself.
When I digged into the __init__.py file in site_packages folder of LGB installation as below, I identified the module which was fit to me (I was working on regression problem). I therefore imported LGBMRegressor and replaced lgb in my code with LGBMRegressor and it started working.
You can check in your code if you are importing the entire class/directory (by mistake) or the target module within the class.
from lightgbm import LGBMRegressor
def LGB_Objective(trial):
parameters = {
'objective_type': 'regression',
'max_depth': trial.suggest_int('max_depth', 10, 60),
'boosting': trial.suggest_categorical('boosting', ['gbdt', 'rf', 'dart']),
'data_sample_strategy': 'bagging',
'num_iterations': trial.suggest_int('num_iterations', 50, 250),
'learning_rate': trial.suggest_float('learning_rate', 0.01, 1.0),
'reg_alpha': trial.suggest_float('reg_alpha', 0.01, 1.0),
'reg_lambda': trial.suggest_float('reg_lambda', 0.01, 1.0)
}
'''.....LightGBM model....'''
model_lgb = LGBMRegressor(**parameters) #here I've changed lgb to LGBMRegressor
model_lgb.fit(x_train, y_train)
y_pred = model_lgb.predict(x_test)
return mse(y_test, y_pred, squared=True)
study_lgb = optuna.create_study(direction='minimize', study_name='lgb_regression')
study_lgb.optimize(LGB_Objective, n_trials=200)
A simple way to solve this problem is export thePYTHONPATH variable enviroment. For example, for Python 2.6 in Debian/GNU Linux:
export PYTHONPATH=/usr/lib/python2.6`
In other operating systems, you would first find the location of this module or the socket.py file.
check the import statements since a module is not callable.
In Python, everything (including functions, methods, modules, classes etc.) is an object.
So, I create a StringIO object to treat my string as a file:
>>> a = 'Me, you and them\n'
>>> import io
>>> f = io.StringIO(a)
>>> f.read(1)
'M'
And then I proceed to close the 'file':
>>> f.close()
>>> f.closed
True
Now, when I try to open the 'file' again, Python does not permit me to do so:
>>> p = open(f)
Traceback (most recent call last):
File "<pyshell#166>", line 1, in <module>
p = open(f)
TypeError: invalid file: <_io.StringIO object at 0x0325D4E0>
Is there a way to 'reopen' a closed StringIO object? Or should it be declared again using the io.StringIO() method?
Thanks!
I have a nice hack, which I am currently using for testing (Since my code can make I/O operations, and giving it StringIO is a nice get-around).
If this problem is kind of one time thing:
st = StringIO()
close = st.close
st.close = lambda: None
f(st) # Some function which can make I/O changes and finally close st
st.getvalue() # This is available now
close() # If you don't want to store the close function you can also:
StringIO.close(st)
If this is recurring thing, you can also define a context-manager:
#contextlib.contextmanager
def uncloseable(fd):
"""
Context manager which turns the fd's close operation to no-op for the duration of the context.
"""
close = fd.close
fd.close = lambda: None
yield fd
fd.close = close
which can be used in the following way:
st = StringIO()
with uncloseable(st):
f(st)
# Now st is still open!!!
I hope this helps you with your problem, and if not, I hope you will find the solution you are looking for.
Note: This should work exactly the same for other file-like objects.
No, there is no way to re-open an io.StringIO object. Instead, just create a new object with io.StringIO().
Calling close() on an io.StringIO object throws away the "file contents" data, so re-opening couldn't give access to that anyways.
If you need the data, call getvalue() before closing.
See also the StringIO documentation here:
The text buffer is discarded when the close() method is called.
and here:
getvalue()
Return a str containing the entire contents of the buffer.
The builtin open() creates a file object (i.e. a stream), but in your example, f is already a stream.
That's the reason why you get TypeError: invalid file
After the method close() has executed, any stream operation will raise ValueError.
And the documentation does not mention about how to reopen a closed stream.
Maybe you need not close() the stream yet if you want to use (reopen) it again later.
When you f.close() you remove it from memory. You're basically doing a deref x, call x; you're looking for a memory location that doesn't exist.
Here is what you could do in stead:
import io
a = 'Me, you and them\n'
f = io.StringIO(a)
f.read(1)
f.close()
# Put the text form a without the first char into StringIO.
p = io.StringIO(a[1:]).
# do some work with p.
I think your confusion comes form thinking of io.StringIO as a file on the block device. If you used open() and not StringIO, then you would be correct in your example and you could reopen the file. StringIO is not a file. It's the idea of a file object in memory. A file object does have a StringIO, but It also exists physically on the block device. A StringIO is just a buffer, a staging area in memory of the data with in it. When you call open() a buffer is created, but there is still the data on block device.
Perhaps this is more what you want
fo = open('f.txt','w+')
fo.write('Me, you and them\n')
fo.read(1)
fo.close()
# reopen the now closed file `f`
p = open('f.txt','r')
# do stuff with p
p.close()
Here we are writing the string to the block device, so that when we close the file, the information written to it will remain after it's closed. Because this is creating a file in the directory the progarm is run in, it may be a good idea to give the file an extension. For example, you could name the file f.txt instead of f.