Does PyIntObject still in python3.x source code? - python-3.x

Does PyIntObject still in python3.x source code,or has it been replaced by PyLongObject? I can't find the code as follows:
typedef struct {
PyObject_HEAD
long ob_ival;
} PyIntObject;

From https://docs.python.org/3.2/howto/cporting.html (long/int Unification):
Python 3 has only one integer type, int(). But it actually corresponds to Python 2’s long() type–the int() type used in Python 2 was removed. In the C-API, PyInt_* functions are replaced by their PyLong_* equivalents.
The best course of action here is using the PyInt_* functions aliased to PyLong_* found in intobject.h. The abstract PyNumber_* APIs can also be used in some cases.
Please check also the following discussion:
How does Python manage int and long?

Related

python type hinting not generating error for wrong type

I was recently checking about type hinting and after reading some theory I tried an simple example as below
def myfun(num1: int, num2: int) -> int:
return str(num1) + num2
a = myfun(1,'abc')
print(a)
# output -> 1abc
Here you can see that I have define num1 and num2 of type int and even after passing num2 value as string it is not generating any error.
Also the function should expect to return int type value but it's not complaining on returning string type value.
Can someone please explain what's going wrong here?
It's called type hinting for a reason: you're giving a hint about what a variable should be to the IDE or to anyone else reading your code. At runtime, the type hints don't actually mean anything - they exist for documentation and usability by other developers. If you go against the type hints, python won't stop you (it assumes you know what you're doing), but it's poor practice.
Note that this differs from statically-typed languages like Java, where trying to pass an argument that's incompatible with the function's definition will produce a compile-time error, and if you pass a differently-typed but compatible argument (e.g. passing a float to a function that expects an int) it will be automatically typecast.
Note that the code you've given will encounter a TypeError if the programmer uses it like they're supposed to, because int cannot be concatenated to a str. Your IDE or linter should be able to see this and give you a warning on that line, which it does based on the type hints. That's what the type hints are for - informing the behavior of the IDE and documentation, and providing a red flag that you might not be using a function in the intended way - not anything at runtime.

String formatting in python 3 without print function

Trying to understand how "%s%s" %(a,a) is working in below code I have only seen it inside print function thus far.Could anyone please explain how it is working inside int()?
a=input()
b=int("%s%s" %(a,a))
this "%s" format has been borrowed from C printf format, but is much more interesting because it doesn't belong to print statement. Note that it involves just one argument passed to print (or to any function BTW):
print("%s%s" % (a,a))
and not (like C) a variable number of arguments passed to some functions that accept & understand them:
printf("%s%s,a,a);
It's a standalone way of creating a string from a string template & its arguments (which for instance solves the tedious issue of: "I want a logger with formatting capabilities" which can be achieved with great effort in C or C++, using variable arguments + vsprintf or C++11 variadic recursive templates).
Note that this format style is now considered legacy. Now you'd better use format, where the placeholders are wrapped in {}.
One of the direct advantages here is that since the argument is repeated you just have to do:
int("{0}{0}".format(a))
(it references twice the sole argument in position 0)
Both legacy and format syntaxes are detailed with examples on https://pyformat.info/
or since python 3.6 you can use fstrings:
>>> a = 12
>>> int(f"{a}{a}")
1212
% is in a way just syntactic sugar for a function that accepts a string and a *args (a format and the parameters for formatting) and returns a string which is the format string with the embedded parameters. So, you can use it any place that a string is acceptable.
BTW, % is a bit obsolete, and "{}{}".format(a,a) is the more 'modern' approach here, and is more obviously a string method that returns another string.

Why isn't from reportlab.graphics.shapes import string working

Python 3.4 reportlab 3.2.0
from reportlab.graphics.shapes import string
Previously worked. Upgraded to newer Python and reportlab and it no longer works.
Was it replaced, eliminated, or moved?
Based on the source on bitbucket the issue is simply that you should have capitalized string such that your import is as follows:
from reportlab.graphics.shapes import String
Which is the way it always should be done according to the PEP 0008 -- Style Guide for Python Code
Class Names
Class names should normally use the CapWords convention.
The naming convention for functions may be used instead in cases where the interface is documented and used primarily as a callable.
Note that there is a separate convention for builtin names: most builtin names are single words (or two words run together), with the CapWords convention used only for exception names and builtin constants.

Is it possible / easy to include some mruby in a nim application?

I'm currently trying to learn Nim (it's going slowly - can't devote much time to it). On the other hand, in the interests of getting some working code, I'd like to prototype out sections of a Nim app I'm working on in ruby.
Since mruby allows embedding a ruby subset in a C app, and since nim allows compiling arbitrary C code into functions, it feels like this should be relatively straightforward. Has anybody done this?
I'm particularly looking for ways of using Nim's funky macro features to break out into inline ruby code. I'm going to try myself, but I figure someone is bound to have tried it and /or come up with more elegant solutions than I can in my current state of learning :)
https://github.com/micklat/NimBorg
This is a project with a somewhat similar goal. It targets python and lua at the moment, but using the same techniques to interface with Ruby shouldn't be too hard.
There are several features in Nim that help in interfacing with a foreign language in a fluent way:
1) Calling Ruby from Nim using Nim's dot operators
These are a bit like method_missing in Ruby.
You can define a type like RubyValue in Nim, which will have dot operators that will translate any expression like foo.bar or foo.bar(baz) to the appropriate Ruby method call. The arguments can be passed to a generic function like toRubyValue that can be overloaded for various Nim and C types to automatically convert them to the right Ruby type.
2) Calling Nim from Ruby
In most scripting languages, there is a way to register a foreign type, often described in a particular data structure that has to be populated once per exported type. You can use a bit of generic programming and Nim's .global. vars to automatically create and cache the required data structure for each type that was passed to Ruby through the dot operators. There will be a generic proc like getRubyTypeDesc(T: typedesc) that may rely on typeinfo, typetraits or some overloaded procs supplied by user, defining what has to be exported for the type.
Now, if you really want to rely on mruby (because you have experience with it for example), you can look into using the .emit. pragma to directly output pieces of mruby code. You can then ask the Nim compiler to generate only source code, which you will compile in a second step or you can just change the compiler executable, which Nim will call when compiling the project (this is explained in the same section linked above).
Here's what I've discovered so far.
Fetching the return value from an mruby execution is not as easy as I thought. That said, after much trial and error, this is the simplest way I've found to get some mruby code to execute:
const mrb_cc_flags = "-v -I/mruby_1.2.0_path/include/ -L/mruby_1.2.0_path/build/host/lib/"
const mrb_linker_flags = "-v"
const mrb_obj = "/mruby_1.2.0_path/build/host/lib/libmruby.a"
{. passC: mrb_cc_flags, passL: mrb_linker_flags, link: mrb_obj .}
{.emit: """
#include <mruby.h>
#include <mruby/string.h>
""".}
proc ruby_raw(str:cstring):cstring =
{.emit: """
mrb_state *mrb = mrb_open();
if (!mrb) { printf("ERROR: couldn't init mruby\n"); exit(0); }
mrb_load_string(mrb, `str`);
`result` = mrb_str_to_cstr(mrb, mrb_funcall(mrb, mrb_top_self(mrb), "test_func", 0));
mrb_close(mrb);
""".}
proc ruby*(str:string):string =
echo ruby_raw("def test_func\n" & str & "\nend")
"done"
let resp = ruby """
puts 'this was a puts from within ruby'
"this is the response"
"""
echo(resp)
I'm pretty sure that you should be able to omit some of the compiler flags at the start of the file in a well configured environment, e.g. by setting LD_LIBRARY_PATH correctly (not least because that would make the code more portable)
Some of the issues I've encountered so far:
I'm forced to use mrb_funcall because, for some reason, clang seems to think that the mrb_load_string function returns an int, despite all the c code I can find and the documentation and several people online saying otherwise:
error: initializing 'mrb_value' (aka 'struct mrb_value') with an expression of incompatible type 'int'
mrb_value mrb_out = mrb_load_string(mrb, str);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~
The mruby/string.h header is needed for mrb_str_to_cstr, otherwise you get a segfault. RSTRING_PTR seems to work fine also (which at least gives a sensible error without string.h), but if you write it as a one-liner as above, it will execute the function twice.
I'm going to keep going, write some slightly more idiomatic nim, but this has done what I needed for now.

python3 how to define ctypes struct for return type from imported library

I'm trying to use ctypes to use fann (a neural network library written in C) in python3. Here is my abridged code so far:
from ctypes import *
cdll.LoadLibrary("/usr/local/lib/libdoublefann.dylib")
fann = CDLL("/usr/local/lib/libdoublefann.dylib")
# Call fann to create a neural network
nn = fann.fann_create_from_file(b'/Users/xxxxx/Code/fanncode/net/nnf_25_1339802027.net')
# this outputs 3909360
print(nn)
If I try and call any other functions in the fann library against the nn variable, which should now be a fann neural network, I either get Segmentation fault: 11 or AttributeError: 'int' object has no attribute 'getMSE' (for example). I think my problem is that according to the ctypes documentation, the variable nn is ending up being an int, whereas the fann documentation for the function fann_create_from_file states:
FANN_EXTERNAL struct fann *FANN_API fann_create_from_file(const char * configuration_file)
So I think I need to declare:
class FANN_API(Structure):
<fields and things which I don't know what they should be>
And then do:
fann.fann_create_from_file.restype = FANN_API
My problem is that I can't find what the struct FANN_API should be. Line 130 of fann.h states #define FANN_API but thats it, no definition or anything follows it.
Am I correct in my guess about needing to define the struct? If so, then how can I find out the format of it to declare in the python code? If not then can anybody suggest what I might need to do/what to read to get my code to work?
Thanks!
You can tell ctypes the arguments and return codes of functions. You should be able to get away with c_void_p (void*) as the type unless you have some reason to manipulate the contents of the structure:
fann.fann_create_from_file.restype = c_void_p
fann.fann_create_from_file.argtypes = [c_char_p]
Note that struct fann * is the return type of your function. FANN_API represents the calling convention. You've said it is defined as #define FANN_API. Being defined as nothing means the default calling convention, so your use of CDLL should be correct.
If you need to define something more specific, post the definition of struct fann.

Resources