This question already has answers here:
Why do some built-in Python functions only have pass?
(2 answers)
Closed 4 years ago.
in many codes, i see classes with functions in them that they just used pass phrase with some comment upon them.
like this native builtin function from python:
def copyright(*args, **kwargs): # real signature unknown
"""
interactive prompt objects for printing the license text, a list of
contributors and the copyright notice.
"""
pass
i know pass does nothing, and its kind of apathetic and null phrase, but why programmers use such functions ?
and also there are some functions with return "" like:
def bin(number): # real signature unknown; restored from __doc__
"""
bin(number) -> string
Return the binary representation of an integer.
>>> bin(2796202)
'0b1010101010101010101010'
"""
return ""
why programmers use such things ?
Your IDE is lying to you. Those functions don't actually look like that; your IDE has made up a bunch of fake source code with almost no resemblance to the real thing. That's why it says things like # real signature unknown. I don't know why they thought this was a good idea.
The real code looks completely different. For example, here's the real bin (Python 2.7 version):
static PyObject *
builtin_bin(PyObject *self, PyObject *v)
{
return PyNumber_ToBase(v, 2);
}
PyDoc_STRVAR(bin_doc,
"bin(number) -> string\n\
\n\
Return the binary representation of an integer or long integer.");
It's written in C, and it's implemented as a simple wrapper around the C function PyNumber_ToBase:
PyObject *
PyNumber_ToBase(PyObject *n, int base)
{
PyObject *res = NULL;
PyObject *index = PyNumber_Index(n);
if (!index)
return NULL;
if (PyLong_Check(index))
res = _PyLong_Format(index, base, 0, 1);
else if (PyInt_Check(index))
res = _PyInt_Format((PyIntObject*)index, base, 1);
else
/* It should not be possible to get here, as
PyNumber_Index already has a check for the same
condition */
PyErr_SetString(PyExc_ValueError, "PyNumber_ToBase: index not "
"int or long");
Py_DECREF(index);
return res;
}
its a TBD (to be done) thing
you know you will need this function, you know what to give it and you know what it returns, but you arent going to write it right now, so you make a "prototype"
sometimes packages will ship with these functions because they expect you to inherit them and overwrite them
Related
I am trying to write some python function in crystal-lang through the C Python API.
My code follows:
METH_VARARGS = 0x0001
#[Link("python3.5m")]
lib Python
alias PyObject = Void*
struct PyMethodDef
name : UInt8*
func : Void*
flags : LibC::Int
doc : UInt8*
end
fun Py_Initialize
fun Py_Finalize
fun PyObject_CallObject(func : PyObject, args : PyObject) : PyObject
fun PyCFunction_NewEx(method : PyMethodDef*, __self__ : PyObject, ) : PyObject
fun PyLong_AsLong(n : PyObject) : Int64
fun PyLong_FromLong(n : Int64) : PyObject
end
def new_method_def(name : String, function, flags : LibC::Int)
x = Pointer(Python::PyMethodDef).malloc(1)
x.value.name = name.to_unsafe
x.value.func = function
x.value.flags = flags
x.value.doc = nil
x
end
Python.Py_Initialize
a = ->(args : Void*) {
puts Python.PyLong_AsLong(args)
Pointer(Void).null
}
name = "num"
number = Python.PyLong_FromLong(1)
Python.Py_IncRef(number)
method = Python.PyCFunction_NewEx(new_method_def(name,a.pointer,METH_VARARGS),number)
Python.PyObject_CallObject(method,Pointer(Void).null)
Python.Py_Finalize
Everything works if I set nil instead of number when in PyCFunction_NewEx, but as the code is, it throws an invalid acces memory exception when Py_Finalize is called.
I can't understand what's causing it.
Can someone help me?
The root problem here is that you're calling a C function of three parameters with only two arguments.
Regrettably, PyCFunction_NewEx is missing from the documentation, despite being a public API function. But all of the examples using it pass three arguments. And if you go to the source:
PyObject *
PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
That's 3.7, but this is the same in 3.5 and in 2.7, and in every other version since the function was added to the API in 2.3. The whole point of NewEx is to allow you to pass a module.
Presumably, the function is expecting that third argument either in a register or on the stack, and you haven't put anything there, so it's completely arbitrary what you're passing. Slightly different code will leave completely different values in those places, so it's not surprising that you get different results:
If the value happens to be 0, that's fine; you're allowed to pass NULL as the module value.
If the value happens to be something that points to unmapped memory, like, say, 1 (as in the raw C long/long long, not a PyLongObject), you should get a segfault from the attempt to incref the module.
If the value happens to be a pointer to some random thing in memory, the incref will work, but will corrupt that random thing. Which could do just about anything, but a mysterious segfault at some arbitrary later point is almost the least surprising thing it could do.
Meanwhile, from a comment:
I am calling PyCFunction_NewEx because PyCFunction_New is a marco in the source code.
If you're using Python 2.3-2.6 or 3.0-3.2, then sure. But in later versions, including the 3.5 you say you're using, CPython goes out of its way to define PyCFunction_New as a function specifically so that it will be present in the API (and even the stable API, for 3.x). See 3.5 for example:
/* undefine macro trampoline to PyCFunction_NewEx */
#undef PyCFunction_New
PyAPI_FUNC(PyObject *)
PyCFunction_New(PyMethodDef *ml, PyObject *self)
{
return PyCFunction_NewEx(ml, self, NULL);
}
So, you really can just call PyCFunction_New.
I am building a C extension module for Python 3.x. I would like to access the functionality of the hex builtin in the Python layer. That is, I would like to convert (form my C code) a PyObject* which is of type 'PyLong_Type' (that is, a plain python int) into a PyObject* which is of type PyUnicode_Type and represents the hexadecimal coding of the int I started with.
This seems like it should be easy, but none of the functions in the integer section of the API guide seem to do it; neither do any of the functions in the string section. Note in particular that PyUnicode_FromFormat doesn't do what I need:
you can't use it with the %S or %R format specifier (you'll get a decimal representation)
you can't use it with the %x format specifier (you'd have to convert the PyObject* to a C int first, which isn't a safe thing to do, since the Python integer might be too large to fit.
This is the implementation of hex:
static PyObject *
builtin_hex(PyObject *self, PyObject *v)
{
return PyNumber_ToBase(v, 16);
}
It's static, but the implementation suggests an easy way to get the same functionality:
return PyNumber_ToBase(your_number, 16);
PyNumber_ToBase also exists in 2.6 and 2.7, though hex doesn't use it in the 2.x line.
Answering my own question, one way to do it is something like:
PyObject *fmt_string = PyUnicode_FromString("{0:x}");
if (!fmt_string)
return NULL;
PyObject *hex_rep_string = PyObject_CallMethodObjArgs(fmt_string, "format", int_obj);
Py_DECREF(fmt_string);
if (!hex_rep_string)
{
return NULL;
}
but it seems there must be a better/more canonical way...
Sorry if this is too vague. I was recently reading about python's list.sort() method and read that it was written in C for performance reasons.
I'm assuming that the python code just passes a list to the C code and the C code passes a list back, but how does the python code know where to pass it or that C gave it the correct data type, and how does the C code know what data type it was given?
Python can be extended in C/C++ (more info here)
It basically means that you can wrap a C module like this
#include "Python.h"
// Static function returning a PyObject pointer
static PyObject *
keywdarg_parrot(PyObject *self, PyObject *args, PyObject *keywds)
// takes self, args and kwargs.
{
int voltage;
// No such thing as strings here. Its a tough life.
char *state = "a stiff";
char *action = "voom";
char *type = "Norwegian Blue";
// Possible keywords
static char *kwlist[] = {"voltage", "state", "action", "type", NULL};
// unpack arguments
if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|sss", kwlist,
&voltage, &state, &action, &type))
return NULL;
// print to stdout
printf("-- This parrot wouldn't %s if you put %i Volts through it.\n",
action, voltage);
printf("-- Lovely plumage, the %s -- It's %s!\n", type, state);
// Reference count some None.
Py_INCREF(Py_None);
// return some none.
return Py_None;
}
// Static PyMethodDef
static PyMethodDef keywdarg_methods[] = {
/* The cast of the function is necessary since PyCFunction values
* only take two PyObject* parameters, and keywdarg_parrot() takes
* three.
*/
// Declare the parrot function, say what it takes and give it a doc string.
{"parrot", (PyCFunction)keywdarg_parrot, METH_VARARGS | METH_KEYWORDS,
"Print a lovely skit to standard output."},
{NULL, NULL, 0, NULL} /* sentinel */
};
And using the Python header files it will define and understand entry points and return locations in the C/C++ code.
I can't speak to Python/C interaction directly, but I can give some background to how these sorts of things work in general.
On a particular platform or implementation, there is a calling convention that specifies how parameters are passed to subroutines and how values are returned to the caller. Compilers and interpreters that target that platform or implementation generate code to conform to that convention, so that subroutines/modules/whatever written in different languages can communicate with each other.
In my assembly class, we had an assignment where we had to write a program using VAX assembler, C, and Pascal (this was in the mid-Cretaceous1980s). The driver was in one of C or Pascal (can't remember which anymore), which called the assembly routine, which called the other routine (which was written in whichever language the driver wasn't). Our assembly code had to pop and push parameters from the stack based on the VMS calling convention.
Each computing platform has (or should have) an application binary interface (ABI). This is a specification of how parameters are passed between routines, how values are returned, what state the machine should be in and so on.
The ABI will specify things such as (for example):
The first integer argument (up to some number of bits, say 32) will be passed in a certain register (such as %EAX or R3). The second will be passed in another specific, register, and so on.
After the list of register is used, additional integer arguments will be passed on the stack, starting at a certain offset from the value of the stack pointer when the call is made.
Pointer arguments will be treated the same as integer arguments.
Floating-point arguments will be passed in floating-point registers F1, F2, and so on, until those registers are used up, and then on the stack.
Compound arguments (such as structures) will be passed as integer arguments if they are very small (e.g., four char objects in one structure) or on the stack if they are large.
Each compiler or other language implementation will generate code that conforms to the ABI, at least where its routines call or are called from other routines that might be outside the language.
We can extract a PyObject pointing to a python method using
PyObject *method = PyDict_GetItemString(methodsDictionary,methodName.c_str());
I want to know how many arguments the method takes. So if the function is
def f(x,y):
return x+y
how do I find out it needs 2 arguments?
Followed through the link provided by Jon. Assuming you don't want to (or can't) use Boost in your application, the following should get you the number (easily adapted from How to find the number of parameters to a Python function from C?):
PyObject *key, *value;
int pos = 0;
while(PyDict_Next(methodsDictionary, &pos, &key, &value)) {
if(PyCallable_Check(value)) {
PyObject* fc = PyObject_GetAttrString(value, "func_code");
if(fc) {
PyObject* ac = PyObject_GetAttrString(fc, "co_argcount");
if(ac) {
const int count = PyInt_AsLong(ac);
// we now have the argument count, do something with this function
Py_DECREF(ac);
}
Py_DECREF(fc);
}
}
}
If you're in Python 2.x the above definitely works. In Python 3.0+, you seem to need to use "__code__" instead of "func_code" in the snippet above.
I appreciate the inability to use Boost (my company won't allow it for the projects I've been working on lately), but in general, I would try to knuckle down and use that if you can, as I've found that the Python C API can in general get a bit fiddly as you try to do complicated stuff like this.
In regex or Script (e.g. one written in python) how can I add
printf("TRACING: %s is called\n", __PRETTY_FUNCTION__);
at entry of all the function definitions, e.g.,
INT4
FunctionNameCouldBeAny (UINT4 ui)
{
// insert here, at entry
printf("TRACING: %s is called\n", __PRETTY_FUNCTION__);
}
for one file xxx.c?
for all c files *.c under directory /work_space/test/src?
Please note, functions defined in the same file may share the same prefix, but not always.
COMMENT 1: -finstrument-functions does not work for my gcc; or else I have to provide __cyg_profile_func_enter()/exit() functions, and find a way to print out the name from binary address. I wonder if there is more efficient way from regex.
Doing the job thoroughly is going to be hard. The problem is recognizing when a function is defined; there can be many possible layouts, and it is hard to recognize all possibilities. For example:
int x() { return 1; } int y(int z) { return z + 13; }
Most ad hoc systems won't detect y, even if they detect and handle x. But that's lousy code layout, and you probably don't indulge in such code layouts.
How do you start your functions?
static void function(int arg1) {
static void
function(int arg1) {
static void
function(int arg1)
{
static void
function(
int arg1
)
{
static void
function
(
int arg1
)
{
Etc. Depending on the notation(s) used, you need to write multiple different regular expressions. Note that if you can't apply heuristics such as '{ at start of line marks start of function - or structure/union definition, or data initialization' (because you use a { at the end of the line containing the function), it gets rather tricky.
You may need to tokenize the input, and keep track of whether you're inside a function definition. Although my example used keywords, you can have functions using user-defined types only:
Xyz *pqr(Abc def)
{
Then, of course, you might have old code written without prototypes:
Xyz *pqr(def)
Abc def;
{
All this is before you get involved in preprocessor stuff, which can really confuse things:
#define BEGIN {
#define END }
Xyz *pqr(Abc def)
BEGIN
...
END
(The original Bourne shell source was, reputedly, written using macros akin to those.)
So, normally, you develop an ad hoc system for recognizing the functions laid out in the style used by your project. One hopes that your project is systematic enough to have a limited variety of choices, but if this is old code that has been maintained over many years by many people, there are likely to be special cases all over the place.
I have a simple solution, that is, mighty Macro! if you only want to apply these to a small set of functions, and they are not called by function pointer
here is the simple solution:
1 locate call functions' definitions and declearations
2 rename them to something else, for example: myfunc to _myfunc, only names changed in these functions so it's fairly easy to change back
3 define a macro, with the name myfunc of which do this: 1) print your log 2) call the original function
you can grab all these functions' declarations to a single macro definition file, do some simple text work(maybe with script lang help, or text editor macro help), but this solution is not good for vast amount of functions, and don't deal with function pointer.
for example, you have function like this:
int myfunc(int arg)
int myfunc(int arg){
return 0;
}
rename myfunc to _myfunc and add a macro named myfunc
#define myfunc(arg)\
print("print whatever you want!");\
myfunc(arg);\
int _myfunc(int arg);
int _myfunc(int arg){
return 0;
}
if macro not good enough, wrap it with another function
int myfunc(arg){
print("print whatever you want!");
return myfunc(arg);
}
int _myfunc(int arg);
int _myfunc(int arg){
return 0;
}
If you want to debug linux kernel with printk and you want to get the call flow at run time, I have a very basic local solution for that.
Open your .c file in notepad++ --> ctrl+H --> Find what: \n{ -> Replace with: \n{ printk \("Your_Name: %s:%d \\n", __func__, __LINE__ \); --> Replace All
Comment kernel parent dir Makefile as like below:
+#KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
Hope it will solve your problem.