I'm compiling several different versions of Python for my system, and I'd like to know where in the source the startup banner is defined so I can change it for each version. For example, when the interpreter starts it displays
Python 3.3.1 (default, Apr 28 2013, 10:19:42)
[GCC 4.7.2 20121109 (Red Hat 4.7.2-8)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
I'd like to change the string default to other things to signal which version I'm using, but I'm also interested in how the whole shebang is assembled. Where is this defined?
Let's use grep to get in the ballpark. I'm not going to bother searching for default because I'll get too many results, but I'll try Type "Help", which should not appear too many times. If it's a C string, the quotes will be escaped. We should look for C strings first and Python strings later.
Python $ grep 'Type \\"help\\"' . -Ir
./Modules/main.c: "Type \"help\", \"copyright\", \"credits\" or \"license\" " \
It's in Modules/main.c, in Py_Main(). More digging gives us this line:
fprintf(stderr, "Python %s on %s\n",
Py_GetVersion(), Py_GetPlatform());
Because "on" is in the format string, Py_GetPlatform() must be linux and Py_GetVersion() must give the string we want...
Python $ grep Py_GetVersion . -Irl
...
./Python/getversion.c
...
That looks promising...
PyOS_snprintf(version, sizeof(version), "%.80s (%.80s) %.80s",
PY_VERSION, Py_GetBuildInfo(), Py_GetCompiler());
We must want Py_GetBuildInfo(), because it's inside the parentheses...
Python $ grep Py_GetBuildInfo . -Irl
...
./Modules/getbuildinfo.c
...
That looks a little too obvious.
const char *
Py_GetBuildInfo(void)
{
static char buildinfo[50 + sizeof(HGVERSION) +
((sizeof(HGTAG) > sizeof(HGBRANCH)) ?
sizeof(HGTAG) : sizeof(HGBRANCH))];
const char *revision = _Py_hgversion();
const char *sep = *revision ? ":" : "";
const char *hgid = _Py_hgidentifier();
if (!(*hgid))
hgid = "default";
PyOS_snprintf(buildinfo, sizeof(buildinfo),
"%s%s%s, %.20s, %.9s", hgid, sep, revision,
DATE, TIME);
return buildinfo;
}
So, default is the name of the Mercurial branch. By examining the makefiles, we can figure out that this comes from the macro HGTAG. A makefile variable named HGTAG produces the variable, and that variable is run as a command. So,
Simple solution
When building Python,
Python $ ./configure
Python $ make HGTAG='echo awesome'
Python $ ./python
Python 3.2.3 (awesome, May 1 2013, 21:33:27)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
Looks like if you add a mercurial tag before you build, then default will be replaced with the name of your tag (source: Modules/getbuildinfo.c : _Py_hgidentifier())
Basically seems like it chooses the name default because that is the name of the branch. Looks like the interpreter is built with the tag name, if one exists, or the name of the branch if no tag (besides tip) exists on the current working copy.
Related
I have been trying to figure out how to comment multiple lines of python code in IDLE shell on MACBOOK pro apple silicon
I have tried to comment with command+D, Command+1, control+D, control+1 but none of the options I tried did work.
On the IDLE Format menu, 'region' usually means 'selected lines. 'Comment out region' and 'Uncomment region' do what they say to a selected region. The default hot keys for Windows and Mac and perhaps Linux are Control-3 and Control-4.
Shell is read-only except for the statement entry area at the bottom -- the line marked with the last >>> prompt and below. So commenting out code above this area is not possible and in this area it has much less use than in an editor.
add ''' in beginning and end of code block
Here is a code example
print('this is print 1')
'''
print('this is inside comments line 1')
print('this is inside comments line 2')
'''
print('this is print 2')
and after running in this in IDLE the output is
Python 3.10.2 (tags/v3.10.2:a58ebcc, Jan 17 2022, 14:12:15) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
= RESTART: C:\Users\User\Documents\Python scripts\Stack overflow solutions\multiline comment\test multi line comment.py
this is print 1
this is print 2
as you can see the the lines between ''' is not executed meaning they have been commented out
Introduction
Image you want to describe a combustion process
In order to sort elements, I created
classes for the describing the substance (eq. class Fuel)
class which describes the combustion (eq. class combustion)
main.py to run an example
Python Files
properties.py
class SolidProp:
def __init__(self,ua):
self._ultimate = Ultimate(ua)
#property
def ultimate(self):
return self._ultimate
class Ultimate:
def __init__(self,ua: dict):
self._comp = ua
#property
def comp(self):
return self._comp
combustion.py
from properties import *
class Combustion:
def __init__(self,ultimate):
self.fuel = SolidProp(ua=ultimate)
main.py
from combustion import *
burner = Combustion({'CH4':0.75, 'C2H4':0.25})
Problem Description
ipython console
In the ipython console (in bash) the following is not recognized automatically (but it can be called):
Python 3.7.2 (default, Dec 29 2018, 06:19:36)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.2.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: run 'main.py'
In [2]: burner.fuel.ultimate.comp
Out[2]: {'CH4': 0.75, 'C2H4': 0.25}
This has something to do that *.ultimate is defined via a decorator in properties.py (see #property) but I would like to be able to get *.ultimate.comp autocompleted in the ipython console, so people can work with it intuitively.
Example
burner.fuel.ultimate is recognized
burner.fuel.ultimate.comp is NOT recognized
I can not see any methods or properties beyond burner.fuel.ultimate in the ipython console. This makes it not intuitively for people to work with it when they do not know those methods exist.
Remark: ipython console of IDE pycharm works fine!?
python console
Running it in the python console:
Python 3.7.2 (default, Dec 29 2018, 06:19:36)
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> exec(open("main.py").read())
>>> burner.fuel.ultimate.comp
{'CH4': 0.75, 'C2H4': 0.25}
Works fine. But why not in the ipython console from a terminal?
Why do semicolons not suppress output in doctests? A workaround is to assign the result, but I am curious as to why this does not work.
"""
>>> 1+1; # Semicolons typically suppress output, but this fails
>>> x = 1+1 # Workaround: assign result to suppress output.
"""
Failed example:
1+1;
Expected nothing
Got:
2
Unlike other languages like C/C++, semicolons are optional terminators for statements in Python, as you can see in the Repl below:
Python 3.6.5 |Anaconda custom (64-bit)| (default, Mar 29 2018, 13:32:41) [MSC v
1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 1 + 1;
2
>>> 1 + 1
2
However, you may observe a different behavior in say IPython:
In [120]: 1 + 1;
In [121]: 1 + 1
Out[121]: 2
The docs for IPython suggest using semicolons to suppress output. However, this behavior is only specific to IPython and does not in any way extend to Python or its standard libraries(like doctest).
You're thinking of MATLAB or IPython or something. Python semicolons don't normally suppress anything. doctest simulates a normal interactive Python session, not an IPython session, so the semicolon does nothing.
The semicolon has no effect at all.
Doctest reads the expected result from the line following the Python statement (i.e. the part after >>>). In your example, there is no result, so doctest expects no result. That's why it reports "Expected nothing". However, 1+1 returns 2.
The second expression, x = 1+1, has no result, so the test is successful (although nothing really is tested).
Try this for example:
"""
>>> 1+1 # without semicolon
2
>>> 1+1; # with semicolon
2
>>> x = 1+1 # not so useful test
"""
I am facing an issue I faced a few times so far.
The issue in question just gets solved by itself every time, without me understanding what is causing it
So what happens is that I start a python virtual environment from my c++ code. That works, afterwards by using the write function I am able to write stuff in that environment. This also works perfectly fine so far. However I am unable to write my last command to the process.
I though about maybe some buffer being full but I didn't really find anything about a buffer in the Qt docs
This is the relevant piece of code:
static QStringList params;
QProcess *p = new QProcess();
params<<"-f"<<"-c"<<"python2"<< "/home/John/Desktop/python.log";
qDebug()<<"parameters: "<<params;
qDebug()<<"going to write";
p->start("script", params);
qDebug()<<"Turning on new user process...";
while(!p->waitForStarted())
{qDebug()<<"waiting for virtualenv to be ready";}
successFailWrite = p->write("import imp;\n");
while(!p->waitForBytesWritten());
successFailWrite = p->write("foo = imp.load_source('myTest', '/home/John/recognitionClass.py');\n");
while(!p->waitForBytesWritten());
successFailWrite = p->write("from myTest import recognitionClass;\n");
while(!p->waitForBytesWritten());
successFailWrite = p->write("myClassObj = recognitionClass();\n");
if(successFailWrite !=-1)
{qDebug()<<"OK written";}
while(!p->waitForBytesWritten());
successFailWrite = p->write("habelahabela\n");
if(successFailWrite !=-1)
{qDebug()<<"OK written";}
QString name = "John";
QString processNewUserParameter= "print myClassObj.addNewUser("+ name +");\n";
QByteArray processNewUserParameterByteArr= processNewUserParameter.toUtf8();
p->write(processNewUserParameterByteArr);
I keep a log file which contains what is being written to the python virtualenv and what is being printed
Script started on Son 27 Aug 2017 20:09:52 CEST
import imp;
foo = imp.load_source('myTest', '/home/John/recognitionClass.py');
from myTest import recognitionClass;
myClassObj = recognitionClass();
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import imp;
>>> foo = imp.load_source('myTest', '/home/John/recognit
<myTest', '/home/John/recogniti onClass.py');
/usr/local/lib/python2.7/dist-packages/sklearn/cross_validation.py:44: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
"This module will be removed in 0.20.", DeprecationWarning)
/usr/local/lib/python2.7/dist-packages/sklearn/grid_search.py:43: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. This module will be removed in 0.20.
DeprecationWarning)
>>> from myTest import recognitionClass;
>>> myClassObj = recognitionClass();
>>>
It does pront "OK written" twice, which on one side proves that I successfully wrote my commands to the process, yet I can't see anything.
As you can see the test sentence "habelahabela" doesn't get written neither.
Does anybody have an idea about what I may be doing wrong?
I know that I am writing my commands to quickly to the environment. Because as you can see I start by writing "import imp", it then gets buffered and a little later the buffer gets flushed and the virtualenv executes the command (this is why you see it twice).
Does anybody see why I can't see the test-sentence and -more importantly- my actual command "print myClassObj.addNewUser("+ name +");\n" being printed to the virtual environment?
Thanks
First of all, there is no sense in writing while(!p->waitForBytesWritten());. waitForBytesWritten already blocks your thread without a while loop and, as the name states, waits until bytes are written. It returns false only if there are either timeout or an error. In the first case you should give it more time to write bytes. In the second case you should fix the error and only then try again.
The same holds for waitForStarted and all other Qt functions starting with "waitFor...".
So the usage looks like:
if(!p->waitForBytesWritten(-1)) // waits forever until bytes ARE written
{
qDebug() << "Error while writing bytes";
}
Regarding the question: I believe the problem (or at least a part of it) is that you write your last 2 messages into p, but you neither wait for bytesWritten() signal, nor use waitForBytesWritten() blocking function. Although, there is probably no error occuring (because p->write(...) does not return -1 at that point), however it does not mean that your message is written yet. In a nutshell, wait for bytesWritten() signal...
QProcess inherits from QIODevice, so I recommend to look its docs and learn about it a bit more.
I'm porting an Application from Linux to OS X and the Boost::Python integration is failing at run time.
I'm exposing my C++ classes like so:
using namespace scarlet;
BOOST_PYTHON_MODULE(libscarlet) {
using namespace boost::python;
class_<VideoEngine, boost::noncopyable>("VideoEngine", no_init)
.def("play", &VideoEngine::play)
.def("pause", &VideoEngine::pause)
.def("isPaused", &VideoEngine::isPaused)
[...]
;
}
I'm importing the library like so:
try {
boost::python::import("libscarlet");
} catch (boost::python::error_already_set & e) {
PyErr_Print();
}
Then I'm inject an instance into the global Python namespace like so:
void VideoEngine::init() {
[...]
try {
auto main_module = boost::python::import("__main__");
auto main_namespace = main_module.attr("__dict__");
main_namespace["engine"] = boost::python::object(boost::python::ptr(this));
} catch (boost::python::error_already_set & e) {
PyErr_Print();
}
[...]
}
It works great in Linux but in OS X an exception is thrown and PyErr_Print() returns TypeError: No Python class registered for C++ class scarlet::VideoEngine.
As far as I can tell the module works without issue when imported via the Python interpreter. It is difficult to test since it designed to be injected as a pre-constructed instance but the class and functions are present as shown below:
$ python
Python 2.7.5 (default, Mar 9 2014, 22:15:05)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import libscarlet
>>> libscarlet.VideoEngine
<class 'libscarlet.VideoEngine'>
>>> libscarlet.VideoEngine.play
<unbound method VideoEngine.play>
Any ideas as to where the incompatibility lies?
Edit: I'm starting to think it might be related to multithreading since my OS X implementation uses a different threading structure, although all of the calls detailed here happen in the same thread. Could that be the cause of such an issue? Probably not the issue since it doesn't work in MS Windows in single-threaded mode.
I have solved this now.
It was caused entirely by Boost::Python being statically compiled and once I recompiled it as a shared library the problem went away entirely, on all platforms.
The lesson: don't compile boost statically. I'm pretty sure there are warnings against it and they should be heeded.