Saturday 31 December 2022

IIEF's

I've been fiddling with Kotlin these last weeks and it's an absolutely amazing language. Honestly I didn't expect it, as it's an static language and I've always considered dynamic languages more appealing to my "Freak inside", but the expressiviness of Kotlin is just incredible. Notice that this expressiviness comes with a price, as there's a learning curve to understand what that beautiful and expressive code is doing. I'm going to use a sample comparing Groovy, JavaScript and Python. Hey, I absolutely love JavaScript and Python, being dynamic languages they still have some rare features that are not possible in Kotlin, but my overall feeling is that at least for non-browser projects, probably I would favor Kotlin for any relatively big project due to its combination of a beautiful language with the amazingly performant JVM.

Same as JavaScript, Kotlin has IIFE's (Immediatelly Invokable Function Expressions). They come very handy when you need a closure, and you'll only have one instance of that closure. In this case, as you won't be invoking that "closure factory" function in several places with different arguments to obtain different instances, but just once, you can just define and invoke the "closure factory" in the place where you first need that instance. As I'm still learning the crazy kotlin syntax, writing the same "one shot" closure factory in Kotlin, JavaScript and Python seemed like a pretty nice exercise to me. Let's see:

This is the Kotlin's most compact code I've come up with. It's beautiful and idiomatic, but I would not say it's easy to read, particularly if you stop coding in Kotlin for some time.


val formatWithCounter = {
    var counter = 0
    { txt: String, wrapper: String -> "${++counter}.${wrapper}${txt}${wrapper}" }
}()


println(formatWithCounter("Paris", "|"))
println(formatWithCounter("Paris", "+"))
// 1.|Paris|
// 2.+Paris+

The JavaScript code is slightly more verbose, but I guess feels a bit clearer. I would say it's the winner for me.


const formatWithCounter = (() => {
    let counter = 0;
    return (txt, wrapper) => `${++counter}.${wrapper}${txt}${wrapper}`
})();


console.log(formatWithCounter("Paris", "|"))
console.log(formatWithCounter("Paris", "+"))
// 1.|Paris|
// 2.+Paris+

The Python code is much more verbose and less elegant. The only Function Expressions in Python are lambdas (that in Python can only contain an expression). We still lack (multi)statement lambdas, as Guido said in 2006 that they were "unpythonic"... which is a reasoning that upsets me quite a bit, and we can not use "def" as an expression. So we have to define the factory function first and invoke it in another line. The same goes for the function being created and returned from the factory, that can not be just a lambda cause in this function I need to add the "nonlocal" line so that the counter variable is trapped by the closure (otherwise, as the variable is being modified, the compiler would consider it as local rather than trap it from the surrounding scope).


def factory():
    counter = 0
    def _format_with_counter(txt, wrapper):
        nonlocal counter
        return f"{(counter:=counter+1)}.{wrapper}{txt}{wrapper}"
    return _format_with_counter   
format_with_counter = factory()


print(format_with_counter("Paris", "|"))
print(format_with_counter("Paris", "+"))
# 1.|Paris|
# 2.+Paris+

An additional note regarding the Python version. I've used the walrus (:=) operator (assignment expressions). These 2 codes are equivalent:


        return f"{(counter:=counter+1)}.{wrapper}{txt}{wrapper}"
        
        # is equivalent to:
        
	counter += 1
        return f"{counter}.{wrapper}{txt}{wrapper}"
        

Saturday 24 December 2022

Bolo de Arroz

I've recently been lucky enough to spend a few days in Lisbon. I already wrote a post 5 years ago about how lovely the city is. Lisbon is still booming, and that massive advantage over other gorgeous European cities that I mention in that post has not done but to increase, as France, Belgium, Germany... are each day more and more submerged by that kind of incompatible and hostile "culture" arrived from abroad and that hopefully is not ravaging Portugal yet. Also, the Left-wing and ecologist mindset in Portugal seems to be rather civilized (the way it was intended to be), far away from the ultra-violent Far-Left, Islamo-Left, Eco-Madness scum in France that propagate self-hatred, racialism and communitarism.
As for cities in Eastern Europe, the fact that they are more conservative is no longer something that bothers me particularly, but the pro-USA fanatism and servility to the fucking North American empire of countries like Poland, the Baltic ones and so on (and their senseless hatred for anything related to Russia) is something that now makes me have a really negative perception of them.

Unexpectedly, I'm not going to talk about architecture, about charming streets, beautiful view-points... but about something I think I rarely talk about in my blog, food!. I mentioned in that previous post that Portuguese sweets are pretty good, and coffee is absolutely delicious and cheap. That statement remains completely true. The most iconic Portuguese sweet, the Pastel de Belem/Pastel de Nata is really popular in I guess most of Europe (for example you have them in Lidl in France and Spain, and in Mercadona in Spain). Though the ones that you buy in a supermarket (the ones in a Portuguese supermarkets are basically the same than those in Lidl abroad) are years ahead from the ones that you can buy in Belem, right out of the oven, with a powdered sugar and a cinnamon sachet, they are still delicious. Portuguese people are very fond of their coffee and sweets, so there are cafetarias/pastelarias in every corner (they are so omnipresent as bars and cafes in Spain) and it's a very common tradition (respected also by the young generations) to go to them to have a coffee and a sweaet in the afternoons (and obviously for breakfast). From the beautiful assortment of sweets that you'll find in a "Pastelaria", there's one that I have rediscovered in this trip, the delicious Bolo de Arroz. Forget you English muffins, Bolo de Arroz plays in an upper level (the same level as French magdalenes). I used to eat them with breakfast in 2008 while working in Lisbon, but in later visits I seemed not to appreciate them so much, and now I think I know why. In those visits I had bought them in MiniPreco supermarkets (part of Spanish Dia chain). This trip I had a Pingo Doce supermarket very close to my hostel, and I bought them there (it has its own "patisserie", cooking stuff in place), the difference is huge, pretty huge, they are way better. I don't think there's any difference betwen these ones in Pingo Doce and those that you can buy in a street patisserie.

I can not talk about Lisbon without bringing up memories of that amazing vegan buffet that has become the icing on the cake in my visits to Lisbon, Jardim das Cerejas. Right in the center of Lisbon you find this small, cosy restaurant, with a neighbourhood feeling, where a buffet with a delicios veggie soup, salad and 4 main dishes along with 2 types of rice costs just 9.5 euros. Add it a freshly squeezed juice (you can mix apple, orange, carrot...) for just 2.5 euros. The food is absolutely delicious. Some of the dishes have a black sauce that I guess is a mix of soja sauce with something more, that has such an intense taste, buff...

Friday 16 December 2022

Boolean Coercion/Conversion, JavaScript vs Python

How a not boolean value is mapped to true or false (either converted using a function or operator, or coerced when used in a boolean context) is one of those things that I need to rethink from time to time. Adding to this that my 2 main languages as of today, Python and JavaScript, have some differences on this topic, I've thought it useful to put a small summary here.

Javascript
This post is a pretty good reference. Falsy values in JavaScript are:
undefined and null (the 2 nullish values), false, NaN, 0 and "" (empty string).
We can convert any value to boolean either with '!!value' or with 'Boolean(value)'

There's something more to bear in mind. Not al falsy values have the same behaviour with the == operator. 0 is equal to false, and "" is equal to false:

0 == false
true
"" == false
true
1 == true
true

undefined == false
false
null == false
false
NaN == false
false

null == undefined
true

Python
Answers here are a pretty good reference. The following values are considered false:
None, False, 0, "" (empty string), any other empty container: (), [] and any empty mapping, for example, {}..
Additionally, a custom class can define the __bool__() method, that will be used when converting instances of that class to boolean.
We can convert any value to boolean either with 'not not value' or with 'bool(value)'

We also have to bear in mind what happens when using the equality operator "==". Only 0 == False and 1 == True are true. All other cases are false:

>>> 1==True
True
>>> 0==False
True
>>> None==False
False
>>> [] == False
False
>>> [] == True
False
>>> 2==False
False
>>> 2==True
False

So the big difference betwewn Javascript and Python regarding boolean conversion/coercion is that in JavaScript an empty array and an empty object are coerced to true, while in Python they are coerced to False. In addition, in Python we can customize the behaviour of our classes by implementing the __bool__ method.

Sunday 4 December 2022

Future vs Future (asyncio vs concurrent.futures)

I've been recently working with Python's very nice concurrent.futures.Executor (the ProcessPoolExecutor particularly). When combining it with the async - await magic I've come across an important gotcha that had me confused for a while.

So I have a function running inside an eventloop. In that function I create a ProcesPoolExecutor and submit some actions to it. As soon as one action completes I want to do something with its result and then continue to wait for the next action, so until all of them are done. My code looked like this:


async def parse_blocks(blocks):
	parser = BlockParser()
	pending_blocks = []
	for block in blocks:
		future_result = executor.submit(parser.parse, block, 0)
		pending_blocks.append(future_result)) 
	while len(pending_blocks):
		done_blocks, pending_blocks = await asyncio.wait(pending_blocks, return_when=asyncio.FIRST_COMPLETED)
		for done_block in done_blocks:
			print("block parsed!)
			result_writer.write(done_block)
	print("all blocks parsed")


The above code was giving me an odd exception in the wait call: TypeError: An asyncio.Future, a coroutine or an awaitable is required. But, executor.submit returns a Future, so what's happening?. Well, executor.submit returns a concurrent.futures.Future, and asyncio.wait is expecting an asyncio.Future. Hopefully we can obtain an asyncio.Future from a concurrent.futures.Future by means of asyncio.wrap_future. I found about it here.

To convert a concurrent.futures.Future into an asyncio.Future, you can call asyncio.wrap_future. The returned asyncio future is awaitable in the asyncio event loop and will complete when the underlying threading future completes. This is effectively how run_in_executor is implemented.

So this code now works fine:


async def parse_blocks(blocks):
	parser = BlockParser()
	pending_blocks = []
	for block in blocks:
		future_result = executor.submit(parser.parse, block, 0)
		pending_blocks.append(asyncio.wrap_future(concurrent_futures_future)) 
	while len(pending_blocks):
		done_blocks, pending_blocks = await asyncio.wait(pending_blocks, return_when=asyncio.FIRST_COMPLETED)
		for done_block in done_blocks:
			print("block parsed!)
			result_writer.write(done_block)
	print("all blocks parsed")


It seems odd to have to different Future classes, that both represent the same, a result that will be provided in the future. Well one of the differences that I get (for example from this discussion) is that asyncio.Future.add_done_callback will invoke its callbacks through the event loop, which I guess is necessary for the coopeative nature of asyncio. A concurrent.futures.Future will not use the eventloop for those callbacks, so this probably would break that cooperativism. This discussion goes a bit more in depth.

Sunday 27 November 2022

Try Expressions

I've recently found that Kotlin supports try-catch-finally expressions (in the same vein as switch expressions). They seem particularly useful to me when executing a block that will assign to a variable or assign a default if the block fails, like this:



fun main (args: Array) {
  val str="23"
  val a: Int? = try { str. toInt () } catch (e: NumberFormatException) {-1}
  println (a)
}


I think this is the first time I see this feature in a programming language, and as usual I've been thinking about how to simulate it, in this case in JavaScript. We can easily simulate the try-catch expression with a tryFn function (emulating try-catch-finally would be more complicated).



function tryFn(fn, exceptions, onErrorFn){
    try{
        return fn();
    }
    catch (error){
        if (exceptions.some(exception => error instanceof exception)){
            return onErrorFn(error)
        }
        else{
            throw error;
        }
    }
}

//val = tryCatch(fn1, [Error1, Error2], onErrorDefaultFn)


We can use this function like this:



class InvalidUrlError extends Error{}
class InvalidPostError extends Error{}
class InvalidUserError extends Error{}


function getPost(url, postId, user){
    if (!url)
        throw new InvalidUrlError("Wrong URL")
    if (!postId)
        throw new InvalidPostError("Wrong Post")
    if (!user)
        throw new InvalidUserError("Wrong User")
    return `Post ${postId} by {user} content`;
}

function formatPost(post){
    return `[[[${post}]]]`;
}

let infos = [
    ["server.org", "1", "xuan"],
    [null, "1", "xuan"],
    ["server.org", null, "xuan"],
    //["server.org", "2", null],
    ["server.org", "3", "xuan"]
]


for (let info of infos){
    let post = tryFn(() => formatPost(getPost(...info)),
        /*catch*/ [InvalidUrlError, InvalidPostError], (ex) => {
            console.log(`caught error: ${ex.constructor.name}`);
            return "No Post"
        } 
    );
    console.log(`post: ${post}`)
}


Well, not sure I will ever use it, but I think it's a valid attempt.

This reminds me a bit of cases where combining await and .catch() for async code rather than wrapping the async call in a try-catch makes the code cleaner. I'm talking about this

Saturday 19 November 2022

FIC Xixón 2021

Sort of a "deja vu". One year ago, when I was going to start to write a post for that year's edition (2021) of FIC Xixon (FICX edition number 59) I realised that I had not published anything about the previous, non-covid, edition (I'd had it partially written for almost 2 years but had forgotten to complete it), so I finished it and published it. Now, while starting my post for 60th edition (that ends today) I've just realised that in the end I had not written anything about the 59th edition... so I'm posting now a mini-summary of what I watched last year.

FIC Xixon 59 took place in one week of 2021 in a beautifully, massivelly rainy November. I only attended 3 films (that seems like a constant since I returned to Xixón in 2018). As I only intended to attend to screenings in Teatro Jovellanos I did not dig much into the program, I just checked what was on display there and came up with these 3 films that did fit my schedule:

  • Maitxable. A very powerful Spanish film. Based on a true story. Maixable, the widow of a Politician (Juan María Jáuregui) murdered by ETA accepts to meet one of the assasins, that while serving his prison sentence has come to regret his actions and moved away from the band.
    If you are interested in the bloody "Basque Conflict" that caused so much pain and suffering, you must watch the Spanish series Patria, that with its gloomy atmosphere perfectly reflects the tensions, contraditions, fanatism and fear that reigned in EuskaHerria for decades.
  • Integralde. Excellent Romanian film. Perfectly mixing hilarious moments with tension and sadness, all of it wrapped in the beauty of Romanian mountains and forests.
  • Bebia, a mon seul desir. A strange story set in a strange place (Georgia feels still rather "exotic" and mysterious to me), filmed in black and white with a rather arty feeling. I did not particularly like it, but do not consider it as a lost of time either.

Monday 14 November 2022

Python Optional Chaining Revisited

I've been thinking again about that Python missing feature (Optional Chaining) I wrote about in this post. It seems like there are no plans to approve the PEP-505 (None aware operators), as there are quite a few opponents to the syntax. I have to admit that it's true that coming across something like:
obj?.client?.getPosts?.("url")?[0]?["title]
is not particularly beautiful and goes rather against the "almost pseudocode" syntax ideal of Python, though anyway I think it's much better than a long chain of if's. Having just a safe_access function added to the standard library would be a good alternative. Thinking of that, I've realised that the implementation of such a function that I wrote for that post is rather stupid :-), does not work with indexing and has the terrible inconvenience of using strings for the attributes names.

The different access errors that we can get when trying to access "things" (attributes, indexing, invoking) on None, or on an object lacking such attributes or indexing or not being callable, etc are: TypeError, KeyError, IndexError, AttributeError, so why not to write our code like this:


try:
	first_title = obj.client.getPosts("url")[0]["title"]
except TypeError, KeyError, IndexError, AttributeError:
	first_title = None
	

Well, that's OK, but it's 4 lines vs 1 line if we had an optional chaining operator. So, let's put the try-catch in a function, and use a lambda to express the access chain, like this:


def safe_access(fn):
    try:
        return fn()
    except (TypeError, KeyError, IndexError, AttributeError):
        return None
        

first_title = safe_access(lambda: obj.client.getPosts("url")[0]["title"])


Honestly I think it looks quite good. Notice that I'm not passing the object being accessed as a parameter to the lambda, I'm directly trapping it as a closure variable. Having a function like this in functools would be even more convenient that implementing the "?" thing, as it would not involve any addition to the language syntax.

Thanks to looking into this topic again I've come across 2 very interesting ideas. One is the Maybe pattern, and its implementation in Python. The other one quite blew me away. An implementation of PEP-505 as a polyfill. So, how can you do that? Well, you can hook into the modules import process and do crazy stuff with them like transforming their source code before python compiles them to bytecodes. This way, you can add extra features to the language as far as you can then compile them to standard python. This is a very powerful feature but that seems rather unknown. The modules import process is documented here

Saturday 5 November 2022

Python Identity and Equality

There are quite a few things we should be aware regarding identity, equality and comparison in Python. I won't explain here the difference between identity (also known as reference equality, mainly in C#) and equality (also known, again mainly in C#, as value equality), it's a general Computer Sciences concept that you should already have clear before reading this post. I already talked about it quite a while ago.

In Python, For identity comparison we use the is and is not operators. They check if 2 variables point to the same object, so they hold the same memory location. ob1 is ob2 is the same as doing id(ob1) == id(ob2).

For equality comparison we use the == and != operators. The behaviour of == and != is determined by the __eq__ and __ne__ methods in the class of our object, so we can customize their behaviour (operator overloading) implementing them in our class. Otherwise, the attribute resolution algorithm we'll end up using object.__eq__ and object.__ne__. These default methods just do an identity/reference comparison. Obviously classes like str or int implement __eq__ and __ne__. This means that str.__eq__ is object.__eq__ is False. You can read more here

Because all types are (direct or indirect) subtypes of object, they inherit the default comparison behavior from object. Types can customize their comparison behavior by implementing rich comparison methods like __lt__(), described in Basic customization.

The default behavior for equality comparison (== and !=) is based on the identity of the objects. Hence, equality comparison of instances with the same identity results in equality, and equality comparison of instances with different identities results in inequality. A motivation for this default behavior is the desire that all objects should be reflexive (i.e. x is y implies x == y).

I've just talked about implementing the __ne__ method. Well, that's not necessary really, we only need to implement __eq__ to customize the equality behaviour for one class. != will try to find a __ne__ method in our instance, and as we have not implemented it it will end up in object.__ne__, that will call __eq__ in that instance (the method that we have implemented) and negate its result. You can find an in depth discussion here.

Python 3.x: indeed, the default implementation of __ne__ calls __eq__ and negates the result (but on the technical level there are some subtleties, please read on).

Hopefully, contrary to JavaScript, we could say that Python does not have type coercion/implicit conversion. I mean, the equality comparison implementations (__eq__, __ne__) in classes like int and str (or the __add__ method) will not automatically convert one type to another if it receives an object of a different type. In Python 5 == "5" is False, while in JavaScript it's True. In the same, way 3 + "5" in Python throws and Exception, while JavaScript converts the integer to string and returns "35".

in operator. The in operator is really useful and expressive. One should wonder how it works regarding value or reference equality. Well, answer gives such an excellent explanation. In short, "in" uses the __contains__ method defined in the container object. For standard containers __contains__ does this:

For container types such as list, tuple, set, frozenset, dict, or collections.deque, the expression x in y is equivalent to any(x is e or x == e for e in y).

Additional considerations. When comparing strings or numbers, we should always use "==" rather than "is". When checking if an object is None, and given that None is a singleton, in most cases using is or == would be equivalent, and is is considered better style. There could be some classes for which __eq__ has been implemented to make comparing to None as True, which I think is very unlikely. In those odd cases you should use ==, unless that you want to skip that odd behaviour...

Sort comparisons. Regarding the >, <, >=, <= comparisons, explains it pretty well.

Some polygloth notes: In Java we use the == operator for identity, and Object.equals (that we can override) for equality. In javascript it's commont to say that we have an identity operator === and an equality operator ==. As there is no operator overloading we can not customize equality ourselves, it's all determined by the algorithms defined by the language, which are very well explained here.

Sunday 16 October 2022

Les Papillons Noirs

I've recently watched online on Arte.tv the amazing series Les Papillons Noirs (Black Butterflies), that I think is available on Netflix. I had seen some advertising on the street and I thought that it was set in the 70's, which was not particularlly appealing to me. Anyway, when I found that it would be available for free in Arte France for one month I decided to give it a try. I got hooked since the first minute. The 2-3 first episodes are really good. It's set in our days, telling a story that starts in the 60's. Albert (masterly played by Niels Arestrup), an old man with just a few months ahead, hires a writer (Modi, a hard guy that after a stay in prison rebuilt himself through writing) to write his biography. Modi (Nicolas Duvauchelle, that I knew from his pretty good performances in Braqo) is in a creative crisis and ends up accepting what apparently should be a boring, mundane task that will get him some cash. It won't be. It's not only Albert's story what is told, but also that of Solance, the love of his life. Two depossesed kids that grow together into two survivors that will end up changing sides, from that of the beaten ones to that of those who beat, and kill, and enjoy with it. The 70's, France, a rich, powerful country (las 30 gloriosas) a working class that can enjoy summer vacations, partying, sexual freedom. A free and optimistic country (so far away from these days), but where things could also go totally wrong.

The recreation of the 70's is amazing, the colorful aesthetic full of life and energy that contrasts with the dark aesthetic of the present, where Modi, his mother and Albert live in shadows. There's this so well chosen female character that makes her appearance in the middle of the series. A tattoo artist whose main role in the story seems at first to further enrich this visual journey by driving us into contemporary, alternative, cool, arty, sensual territories, and that will end up being a pivotal piece of this masterful story.

The characters grow and grow as the story evolves, so the last episodes are really tense, gripping, unsettling, thrilling... and then you have this twist in the story that left me in shock. A twist that I would almost compare to the one in Incendies (so if you've read my review of that Quebecoise masterpiece you get an idea of how much that means coming from me). When the last episode ended I was left with contradictory feelings. On one hand a profound satisfaction as I felt lucky to have spent my time with such an amazing story. On the other hand, the bad feeling left by the realistic question to this answer: how long will it take until I come across another story so good as this one? A long time I'm afraid.

Monday 3 October 2022

Using async-await in Python to avoid Stack Overflows

Last year I wrote a post explaining how we can avoid stack overflows in javascript deep recursive functions by making the function async and placing an "await 'nothing';" before the recursive call (just read that post if you want a reminder). That works fine in JavaScript because you can await anything, not just a Promise (well indeed it will be converted in a Promise.resolve("anything")). Awaiting that already resolved promise will anyway suspend the current function, putting in the microtask queue the "continuation" function for that promise, that is, the call that will resume that function in the point after the await.

Things are a bit different in Python asyncio. You now that we have several types of awaitables (coroutines, Tasks, Futures...). In this post, when I say coroutines I'm referring to native coroutines, the ones that you define with the async keyword. I'm not talking about the coroutines that you could define in older versions of python by means of some decorator (honestly I have never used them). Native Coroutines return a Coroutine object, and its code will not run until you await for it. Additionally, they don't return a Future, they just get suspended/resumed in their await calls, and end up returning a value, but not as the result attribute of a Future created by the runtime. This is pretty different from JavaScript async functions, that always create a Promise that gets resolved to the value returned by the functions after its different suspensions/resumes. This is pretty important because a Python coroutine will suspend if the last coroutine in the stack of coroutine calls explicitely yields the control to the event loop. Coroutines are implemented as generators, so this "yield control" means yielding a Future or just None. When the future reaches the event-loop it will set a callback in the future (via add_done_callback) to resume the coroutine. This answer explains it nicely:

This part is a common misconception. Python's await doesn't mean "yield control to the event loop", it means "start executing the awaitable, allowing it to suspend us along with it". So yes, if the awaited object chooses to suspend, the current coroutine will suspend as well, and so will the coroutine that awaits it and so on, all the way to the event loop. But if the awaited object doesn't choose to suspend, as is the case with aprint, neither will the coroutine that awaits it.

There are several deep-dive articles that have helped me understand (maybe not fully, but at least to a "that's enough level") how coroutines are implemented by means of generators, yield-from, tasks and futures. This article is probably the most complete thing you'll find around. And this and this are also a good read. Bear in mind that as far as I've understood, for a chain of coroutine calls to run you will always have a Task that is controlling it, either directly created by you invoking asyncio.create_task, or created by the event-loop itself. When I mentioned above that coroutines yield futures to the eventloop, well, indeed the Future reaches the Task (that invoked the coroutine with task._step -> coroutine.send), so it's the Task who adds a callback to the Future. From the tenthousandmeters article:

What does task.__step() do with a future? It calls future.add_done_callback() to add to the future a callback that reschedules task.__step(). If the result is already available, the callback is invoked immediately. Otherwise, it's invoked when someone/something sets the result by calling future.set_result().

Being aware of those differences between Python and JavaScript, I thought I would not have problems to implement the "prevent stackoverflow" trick in Python as I did in JavaScript. Basically, instead of a simple "await 'whatever'" I would have to do an await asyncio.sleep(0)" that is the official way to return control to the eventloop. That way the current function gets suspended, meaning that we temporarily exit it, and when resuming it, I was assuming that the stack would be clean, meaning that the stack would not keep growing to an overflow. I was wrong. Given a simple recursive function:


def build_message(msg, counter):
    """
    Normal recursion. Will overflow the stack at around iteration 1000
    """
    if counter == 0:
        return msg
    # print(f"{counter}")
    msg += "a"
    return build_message(msg, counter-1)

If I write it in an async way like this, and invoke it with counter = 1000, it fails:


async def async_build_message_KO(msg, counter):
    """
    Try to prevent the stackoverflow by making it a coroutine and suspending it via asyncio.sleep
    It does not work
       """
    if counter == 0:
        return msg
    sleeper = asyncio.sleep(0.001)
    print(f"{msg[0]} - {counter}")
    # print(f"{counter} - {type(sleeper).__name__}")
    await sleeper

    msg += "a"
    return await async_build_message_KO(msg, counter-1)

The above code causes a stackoverflow once the stack reaches the 1000 items limit. I tried sleep(0.001) (not just with sleep(0)) to make sure that we are really suspending the execution for a (minimum) amount of time. I was quite confused, and googling around I found a solution, invoking the recursion via create_task. With the above I can invoke it with counter=5000 and it will work nicely. Notice that it works perfectly fine both if using tail recursion, as in the original sample, and if I move the "msg += a" operation after the recursive call. (notice that python does not feature tail-call optimizations)


async def async_build_message_OK(msg, counter):
    if counter == 0:
        return msg
    print(msg[0])
    # It works fine, both if implemented as Tail recursion:
    # msg += "a"
    # return await asyncio.create_task(async_build_message_2(msg, counter-1))
    
    # or as Non Tail recursion:
    msg = await asyncio.create_task(async_build_message_OK(msg, counter-1))
    msg += "a"
    return msg


OK, that works, nice, but why does my first approach fail? Well, it took me time to understand it, but it makes sense now. First, the stack managed by the python interpreter representing the python function calls is kept in the heap as a list of stackframe objects (then for sure the native CPython code of interpreter uses a "normal stack" but it manages the python code list of stackframes as a stack, with a limit of how many frames we can have in it). Second, generators (and as I've just said, native coroutines are based on generators) are implemented in python in a very interesting way:

the key thing to remember is that python generators encapsulate a stack frame and a code object. The stack frame is allocated on heap memory and holds a pointer to the last bytecode instruction that was run on a code object within the context of the stack frame. It is the last instruction pointer which tells the CPython interpreter which line to execute next when a generator function is resumed. These are the core building blocks over which generator functions thrive.

So each native coroutine is linked to a stack frame, and even if I'm suspending the coroutine first with await asyncio.sleep() as I resume it and do the recursive call, the coroutines stack up, along with their stack frames. When I stack up 1000 of them, the stack crashes.

Once we have managed to understand why the first attempt was failling, we shoud also try to understand why the second attempt, using create_task works! The thing is that in that case we have coroutines, but they dont form a stack of coroutine calls, because each of them has been started by a task, so in the end up with a chain of Tasks in the heap (with each task managing a coroutine), not with a chain/stack of couroutines. Those chained tasks (or Futures) are chained with callbacks set by add_done_callback and that will be invoked by the eventloop as the corresponding set_result is invoked. So the call to asyncio.create_task to execute the recursive call prevents the creation of a stack of coroutines. Then, when the last coroutines ends and returns a value it sets the result of its controlling task, so the eventloop schedules the Task that was controlling the coroutine that created that task (its task._step() method as I previously mentioned), and it will resume the coroutine, executing the "post-recursion code". This in turns finishes the coroutine, that sets the result of its controlling task, and so on.

Thinking it twice, this python solution is doing just what my JavaScript code from last year does implicitly. As JavaScript async functions always return a Promise, the recursive calls are not directly linked, but linked through those returned Promises, so no stack of calls and no stack overflow.

By the way, Javascript generators seem to be implemented in a very similar way to Python ones, as explained here. The data is kept between the different invokations (pause/resume) of the generator by means of maintaining the ExecutionContext object between calls, and a pointer to the current position in the code is also kept. Additionally, async-await in JavaScript seems also to be based on generators

This iterator object is used to control the generator function and keeps alive the execution context of the generator function. The iterator object exposes a [[GeneratorLocation]] property which I assume keeps track of where the program execution of the generator is paused.

The Python and JavaScript implementations are pretty interesting when you come from a C# background, because in .Net generators (oddly called iterators...) are implemented through tons of compiler magic that ends up creating sort of state machines.

Thursday 29 September 2022

La Rouviere

This is one more post praising Marseille as an amazingly beautiful city. Obviously I'm talking about the architecture and the natural landscape, and keeping aside the "Human landscape": criminality, drug dealing, Islamism, vandalism, far-left Fascist scum (calling themselves antifascists...). If you get to Marseille by train when you get out of the pretty nice Saint Charles Station probably the first thing that you'll see (apart from some Maghrebian and Sahelian dealers) is a small mountain not so far away crowned by a gorgeous Neo-Bizantine church. That's Notre-Dame de la Garde, the magnificent church that dominates the whole city, looking after its inhabitants (well, I hope only for those that deserve it). Additionally the stairs that go down from the station to Boulevard d'Athens to take to you to the city center (the station is in a slightly elevated position) are just imposing, with those two mesmerizing female sculptures representing the African colonies and the Asian colonies of the good, old France (the day some indigenist-anticolonial-"so called antifascist" scumbags will try to damage them "je vais peter un cable").

When you climb up to La Bonne Mere (as the Notre-Dame de la Garde is commonly known), it's not just the building what will marvel you, it's the amazing views. I'm used to cities, Lisbon is the perfect example, where you climb up to some view point to see from there one part of the city. Then you climb up to another one with a different orientation to see another part of the city, and so on. But the 150 meters high mountain hosting Notre Dame de la Garde is just in the center of Marseille, and you can walk around the church to see the whole city, the sea and the islands to the West, the massive city to the North and the East (surrounded by an important mountain range), the imposing Calanques to the South... it's just outstanding.

Looking South-East you'll see some groups of high-rise residential buildings (grand-ensembles) that seem to climb up the mountains. For an urban freak it's a beatiful image. There are several groups of them (each group is a "cité") but one one of them is really massive. I had always assumed it would be some HLM (public housing) nightmare, totally controlled by Islamists and dealers, like a sort of Afghanistan only that dealing cocaine and weed to the locals (infidels from other neighbourhoods) rather than exporting opium to far away countries. Some days ago I decided to investigate and to my total surprise it's not like that at all!

That grand-ensemble is called La Rouviere and is not a public housing mess, but "normal housing", with most of the flats being owned by those living in them. The access to the residential area (or at least to the buildings themselves) is controlled by guardians, so it's a peaceful community of almost 9000 people. The area was built in the 60's and filled mainly by Pieds noir, the French population that had to flee Algeria when it gained independence, after having lived there for generations, after having built a modern and well functioning society and economy that would collapse in just a few years of "independence".

It's not surprising to find an "article" in that left-wing propaganda pamphlet called "Le Monde" where the people living in La Rouviere are called racists and fascists for doing their best to keep their cité peaceful and European by promoting that the new inhabitants that get there when some flat becomes vacant have the same "cultural codes" that those living there. Oh, yes, it's terrible. Moreover, bearing in mind that many of the current inhabitants descend from the Pieds Noirs that first got to the cité, one should for sure ask them to welcome Algerians into the community. It would be a very progressist way to respond to the "la valise ou le cercueil" (the suitcase or the coffin) choice given by Algerians to the Pied-Noirs in 1962... Hopefully some people still have common sense, have learnt lessons from recent history and do not accept the woke, progressist crap.

By the way, this wikipedia article about Marseille's urbanism is really interesting.

Saturday 24 September 2022

European Hypocrisy, European Suicide

Equality and Unequality are terms constantly and dangerously used by "progressist" people. Equality seems like a nice idea, but when it's constantly applied, not partially. You should treat equally, give equal opportunities, to those that deserve them equally based on their behaviour, effort, attitude...

Little after the start of the War between USA/NATO and Russia in Ukraine, some NGO's, immigrationists, well thinking people... took almost no time to complain about the different attitude of European authorities and European populations towards refugees depending on whether they come from Ukraine or from a non European country. I agree with this different treatment, cause I don't think all migratory waves are the same. So this behaviour shows that it seems like regardless of the multicultural propaganda some people still have some common sense. Europe should be more open to immigration coming from a country with a cultural background similiar to ours, like Ukraine (or Russia if it were the case) than to people coming from countries with a totally differente culture (mainly coming from a totally different religion). The first ones will easily integrate and that fraction of them that will cause problems will do it in the same proportion as local population does cause problems. As for the second ones, for sure some of them will integrate and contribute, but too many of them will not. So it's obvious that we should not welcome them with the same openness.

One should wonder why Europe has not reacted in the same way to the invasion of Ukraine by Russia that to the invasion of Northern Cyprus by Turkey. OK, that invasion took place in 1974, but it continues to this date, so it's not late to kick off the Ottoman scum from that European island.

One could also wonder why the European reponse to the the Ukraine-Donbass conflict and the Serbia-Kosovo conflict has been so different. On both cases we have one region that wants to break away from one country, for some time in the future joining another country (Russia or Albania). Indeed, there are some massive differences between Kosovo and Donbass. Kosovo is the birth place of Serbia, but during Ottoman rule Muslim Albanians started to migrate into the area and at some point these invaders (I call them invaders because they don't have the same religion and culture as the original Serbian population) became majoritary and started to ask for independence (and kill Serbs). Oddly enough, in this case Europe did not remain neutral, but sided with the breakaway region (and as part of that NATO bombed Serbian cities like Belgrad). Ukraine has a quite different history from Serbia and what is now called Ukraine (excluding Crimea, that was only part of Ukraine a few decades due to an odd decision by Krushev) was never a country until last century. I support people's right to decide to form a new country or to join another country, always that there is some sort of historical logic and fairness, but this goes in both senses, the right of Ukraine to exist, and the right of the Donbass to break away and join Russia.

One could also wonder why the European Union does not seem to give a shit about Azerbaijan and Turkey (both Muslims countries of Turkic ethnicity) slaughtering the Christian Armenians in October 2020 and now again. Notice that it was not only the Azeri army and Turkish militia, but also yihadist groups relocated from Syria by the Turkish government.

It's clear to me that in a conflict between countries of different civilizations (Christian, European Cyprus vs Muslim Turks, Christian, Slav Serbs vs Muslim Albanians, Christian Armenians vs Muslim Turks) we should actively support those belonging to our same civilization. In the case of the Donbass, Ukraine and Russia, where Orthodox Christian Slavs are fighting Orthodox Christian Slavs, I don't think we should support any side. What we must do is help innocent civilians and force all parts to sit on a table and negotiate peace. If that peace means and independent Donbass, a Russian Donbass or an Autonomous Donbass in Ukraine (where Russian language and culture would be respected), that should not be a main concern for us.

What for sure we should not do is turn the USA puppet, psychopath clown Zelensky into a hero. That nationalist "hero" prefers to see his whole country being destroyed than to negotiate with Russia the future of one part of that country where an important percentage of the population feel much closer to Moscow than to Kyiv... That psychopath has been pushing all of Europe into a war with Russia. An Ukranian "patriot" that defends the interests of the USA rather than the lives of his people. An American agent that has helped to finish off our relation with Russia and to achieve the complete vassalization of Europe to USA... Hope one day he will pay for all what he has done to his own people and to the rest of Europe.

Monday 19 September 2022

Python AsyncExecutor

After writing my JavaScript AsyncExecutor it became clear that at some point I would have to do a Python AsyncExecutor :-)

I already did a very basic post some months ago about the differences between JavaScript and Python async/await. The way async/await, Native Coroutines, Tasks and Futures works in Python seems more complex to me than async/await and Promises in Javascript, though maybe it's just that I'm more familiar with async code in JavaScript.

Anyway, implementing an AsyncExecutor is not much different. In Python we have not just Promises as awaitable objects, but Native Coroutine objects, Futures and Tasks (that indeed derive from Future). So we submit to the AsyncExecutor "awaitable functions" (functions that return any of those awaitable objects), along with its parameters. The AsyncExecutor returns a Future, that will be resolved (will have its result set) when the corresponding asynchronous function completes. The _run_action() method takes care of running the "awaitable function" when a slot is available. _run_action is a Native Coroutine, so when we invoke it either from submit() (for the first submitted functions, before filling the available slots) or from _process_result() (as slots are released), 2 functions that are not coroutines themselves, we have to use asyncio.create_task(self._run_action(action)). This is the main difference with the JavaScript version, where functions marked as async are executed immediatelly, with no need of awaiting them (or creating a task). I copy the code here (and I have also uploaded it to a gist)


import asyncio
from dataclasses import dataclass
import random
from typing import Any
import json

@dataclass
class AsyncAction:
    future: asyncio.Future
    awaitable_fn: Any # function that returns an awaitable (coroutine, a task...)
    args: list[Any]
    kwargs: list[Any]


class AsyncExecutor:
    def __init__(self, event_loop: asyncio.AbstractEventLoop, max_running_actions: int):
        self.event_loop = event_loop
        self.max_running_actions = max_running_actions
        self.running_counter = 0
        self.not_launched_actions = []

    def submit(self, awaitable_fn, *args, **kwargs) -> asyncio.Future:
        """
        receives a function to be executed when there's one available slot. That function returns and awaitable
        """
        future = self.event_loop.create_future()
        action = AsyncAction(future, awaitable_fn, args, kwargs)
        if self.running_counter < self.max_running_actions:
            self.running_counter += 1
            # _run_action returns a coroutine, so if I'm not awaiting it need to run it as a task
            #self._run_action(action)
            asyncio.create_task(self._run_action(action))
        else:
            self.not_launched_actions.append(action)
        return future

    async def _run_action(self, action: AsyncAction):
        result = await action.awaitable_fn(*(action.args), **(action.kwargs))
        self._process_result(action, result)

    def _process_result(self, action: AsyncAction, result: Any):
        self.running_counter -= 1
        action.future.set_result(result)
        if len(self.not_launched_actions):
            self.running_counter += 1
            asyncio.create_task(self._run_action(self.not_launched_actions.pop(0)))           


async def mock_download(url: str, delay: int):
    print("starting mock download")
    await asyncio.sleep(delay)
    return url.upper()

def create_download_task(url: str, delay: int):
    print(create_download_task.__name__)
    return asyncio.get_running_loop().create_task(mock_download(url, delay))
 

async def main():
    async_executor = AsyncExecutor(asyncio.get_running_loop(), 4)
    futures = []
    for i in range(0,10):
        delay = random.randint(1, 4)
        if i % 2 == 0:
            future = async_executor.submit(mock_download, f"www.jesoutienslapolice.fr/post_{i}", delay)
        else:
            future = async_executor.submit(create_download_task, f"www.jesoutienslapolice.fr/post_{i}", delay)

        future.add_done_callback(lambda fut: print(f"{fut.result()} done"))
        futures.append(future)
    future = async_executor.submit(mock_download, f"www.jesoutienslapolice.fr/post_{i}", delay)
    future.add_done_callback(lambda fut: print(f"{fut.result()} done"))
    futures.append(future)
    print(f"{len(futures)} submitted")

    results = await asyncio.gather(*futures)
    print(f"all finished: {json.dumps(results, indent=4)}")


asyncio.run(main())

As we've seen, asyncio.create_task is really important in python's asynchronous code. This discussion helps to understand what it does.

It submits the coroutine to run "in the background", i.e. concurrently with the current task and all other tasks, switching between them at await points. It returns an awaitable handle called a "task" which you can also use to cancel the execution of the coroutine.

It's one of the central primitives of asyncio, the asyncio equivalent of starting a thread. (In the same analogy, awaiting the task with await is the equivalent of joining a thread.)

Friday 16 September 2022

Le Brasilia

At the start of this post from 1 year ago I mention what a beautiful city Marseille is and how much I love its urban landscape. Of course you have tons of classic stuff, of course you have quite a few recent pieces of interest. It's not just the tour CMA/CGM or Jean Nouvel's Marseillese tour (that indeed I don't find particularly appealing) but the whole Euromediterranee neighbourhood with its offices and hotels, the long avenue with the tram running along it, the 15-20 stories residential buildings, etc that makes a really pleasant example of how a modern neighbourhood in a European city should look.

Tours CMA/CGM et La Marseillese

Moving a few decades back, we find that also at that time Marseille did some good efforts to look like a modern city and reclaim its place as a Mediterranean capital. There are 2 high-rise buildings (for European standards they are skyscrappers) from the 70's that (slightly surpassing or almost reaching the 100 meters mark) will catch your eye when looking eastwards from Notre Dame de la Garde (la Belle Mere), the residential tower Le Grand Pavois and the offices tower Tour Mediterranee. They are the common example of architecture of the 70's that pop up in many European cities of similar size, trying to create a strong architectural signal.

Though I consider that kind of towers pretty interesting, I understand that for most people (that are not urban architecture freaks like me) those buildings have hardly any interest, and the only reference to architecture of the 50's-60's-70's in Marseille that you'll read about is La Cité Radieuse, designed by Le Corbusier. I'm not a fan at all of this guy, but I think his concept of Unité d'Habitation has some interest. For sure paying a visit to La Cité Radieuse is a good idea, but I would not give it much precedence in a list of things to see and do in Marseille. Indeed, it was not until my eighth visit to the city that I decided to go to see it.

That time in 2018, when walking along Boulevard Michelet from Rond-Point du Prado on my way to Cité Radieuse, one imposing building on the right deeply caught my eye, mainly because of its sculptural outer stairs (fire escape). I did not think about it anymore since then, but last week when I was again in Marseille and I happened to be around the Rond-Point du Prado area, I decided to take another look to that surprising building. I found it even more impressive than the first time, and I found out that is called "Le Brasilia". The Ministére de la Culture site has an interesting entry about the building, giving some pretty good information. I think the building is like 22 stories high, but it seems it had been initially planned to reach 30 stories, which would have made it even more impressive. The architect, Fernand Boukobza was pretty much influenced at that time by Le Corbusier and La Cité Radieuse, and probably this is his most important work. It's interesting that he designed several HLM ensembles, the terrifying French social housing complexes (I say terrifying because of part of the population living there, not because of the architecture, that in many cases seems pretty decent to me). Indeed, it seems like he designed the infamous La Castellane, that has become one of the worst neighbourhoods in Europe.

Le Brasilia

Monday 29 August 2022

Safe Dereferencing in Python

There's a beautiful feature that I first came across with in Groovy many years ago and that over time has made it into C# first and TypeScript/JavaScript recently. It goes under different names: Safe Navigation, Save Dereferencing, Optional Chaining. Well, I'm refering to the "?" operator when accessing an attribute, that will return null (undefined in JavaScript) if the attribute is missing, and will not continue with ensuing attribute look ups if we were in a chain. I mean:

country?.capital?.location?.xCoordinate;

Notice that optional chaining also works for method invokation, using in JavaScript this odd syntax: ob.method?.()

It's one of those few features that I miss in Python. There is proposal PEP 505 to add it to the language, but for the moment it's in deferred state. So, same as I did 10 years ago when JavaScript was missing the feature and I sort of implemented a workaround, I've written a simple python function to sort of simulate it. We pass the chain as a List of strings (representing the attributes) or tuples (representing parameters for a method invokation):

UPDATE: The below implementation is quite a crap, for a better one check this follow-up post.


def safe_access(ob, chain):
    """
    sort of "safe accessor" (javascript's x?.attr?.attr2...)
    this version includes method invocation, so it's quite different from my getattr_chain.py
    """
    cur_value = ob
    for item in chain:
        if isinstance(item, str): #accessing attribute
            cur_value = getattr(cur_value, item, None)
        else: #invoking
            cur_value = cur_value(*item)
        if cur_value is None:
            return None
    return cur_value


class Person:
    def __init__(self, name, age, profession):
        self.name = name
        self.age = age
        self.profession = profession

class Profession:
    def __init__(self, name, salary):
        self.name = name
        self.salary = salary
    
    def format_profession(self, st1, st2):
        return f"{st1}-{self.name}-{st2}"

p1 = Person("Francois", 4, Profession("programmer", 50000))

print(safe_access(p1, ["name"]))
print(safe_access(p1, ["city"]))
print(safe_access(p1, ["city", "name"]))
print(safe_access(p1, ["profession", "salary"]))
print(safe_access(p1, ["profession"
    , "format_profession", ("¡¡", "!!")
    , "upper", ()
]))

In JavaScript, if we try to invoke a method, but it exists as a data attribute, not as a function, the optional chaining will throw an error: TypeError: xxx is not a function


> ob = {name: "aa"};
> ob.name?.();
Uncaught TypeError: ob.name is not a function

I'm also doing that in my python code (you'll get a TypeError, xxx is not callable). I think it could make sense to return None rather than throwing an exception, for that we would update the invokation part in the above function with a callable check, like this:


            # cur_value = cur_value(*item)

            # if not callable, return None also
            if callable(cur_value):
                cur_value = cur_value(*item)
            else:
                return None


Safe dereferencing/Optional Chaining is related to other 2 features, also present in C# and recently in JavaScript (when I wrote this post it had not made it into JavaScript yet), the null coalescing operator and the null coalescing assignment. I think the aforementioned deferred PEP should also address these 2 things. For the moment, depending on the data that you are expecting, you could check with (as we used to do in JavaScript until recently) or. I mean a = b or c (rather than an hypothetycal: a = b ?? c). You can take a look at this discussion to see the possible issues with this approach.

Friday 19 August 2022

AsyncExecutor

It's interesting how depending on what you have been working on lately you can come up with different solutions for the same issue. 3 years ago I posted about a solution to limit the number of asynchronous calls running in parallel in JavaScript. Basically I was asking permission to a TicketManager that was like a sort of C#'s SemaphoreSlim.

In the last months I've been working mainly with Python, and I've discovered the so nice functionality provided by ThreadPoolExecutor and ProcessPoolExecutor, and before the prospect of limiting async calls in JavaScript again (e.g. limiting the number of http requests in progress to the same server at a given time), I've naturally come up with the idea of implementing an AsyncExecutor.

So we have a class with a max number of slots (actions), and we submit to it asynchronous functions and their parameters. If it has some free slot it will run the asynchronous function and return the Promise returned by that call. If there are no slots, it puts the funtion in a queue, and returns a Promise that will get resolved once the function has been invoked and resolved. That's all:


class AsyncAction{
    constructor(fn, args, resolveFn, rejectFn){
        this.fn = fn;
        this.args = args;
        this.resolveFn = resolveFn;
        this.rejectFn = rejectFn;
    }
}

export class AsyncExecutor{
    constructor(maxRunningActions){
        this.maxRunningActions = maxRunningActions;
        this.runningCounter = 0;
        this.pendingActions = [];
    }

    submit(fn, ...args){
        let resolveFn, rejectFn;
        let pr = new Promise((resFn, rejFn) => {
            resolveFn = resFn;
            rejectFn = rejFn;
        });
        let action = new AsyncAction(fn, args, resolveFn, rejectFn);

        if (this.runningCounter < this.maxRunningActions){
            this._runAction(action);
        }
        else{
            this.pendingActions.push(action);
        }

        return pr;
    }

    async _runAction(action){
        this.runningCounter++;
        let result;
        try{
            result = await action.fn(...(action.args));
        }
        catch (ex){
            this._processActionResult(action, false, ex);
            return;
        }
        this._processActionResult(action, true, result);
    }

    _processActionResult(action, successful /*bool*/, result){
        this.runningCounter--;
        if (successful){
            action.resolveFn(result);
        }
        else{
            action.rejectFn(result); //here result is an exception
        }
        if (this.pendingActions.length){
            this.runningCounter++;
            this._runAction(this.pendingActions.shift());
        }
    }
}

You can test it with this:


import {AsyncExecutor} from "./asyncExecutor.js"


function asyncSleep(interval){
    return new Promise(resFn => {
        setTimeout(resFn, interval);
    })
}

async function mockDownload(url, delay){
    console.log(`starting download: ${url}`);
    await asyncSleep(delay);
    return url.toUpperCase();
}

let executor = new AsyncExecutor(3);
let asyncDownloads = []
for (let i=0; i<= 6; i++){
    asyncDownloads.push(executor.submit(
        mockDownload, 
        `www.resistence.fr/post_${i}`, Math.floor(Math.random() * 4000)
    ).then(result => {
        console.log(`download ${i} finished`);
        return result;
    }));
    console.log("after submit");
}

let results = await Promise.all(asyncDownloads);
console.log(`results: ${JSON.stringify(results, null, "\t")}`);

/*
starting download: www.jesoutienslapolice.fr/post_0
after submit
starting download: www.jesoutienslapolice.fr/post_1
after submit
starting download: www.jesoutienslapolice.fr/post_2
after submit
after submit
after submit
after submit
after submit
starting download: www.jesoutienslapolice.fr/post_3
download 2 finished
starting download: www.jesoutienslapolice.fr/post_4
download 3 finished
starting download: www.jesoutienslapolice.fr/post_5
download 0 finished
starting download: www.jesoutienslapolice.fr/post_6
download 1 finished
download 5 finished
download 6 finished
download 4 finished
results: [
        "WWW.JESOUTIENSLAPOLICE.FR/POST_0",
        "WWW.JESOUTIENSLAPOLICE.FR/POST_1",
        "WWW.JESOUTIENSLAPOLICE.FR/POST_2",
        "WWW.JESOUTIENSLAPOLICE.FR/POST_3",
        "WWW.JESOUTIENSLAPOLICE.FR/POST_4",
        "WWW.JESOUTIENSLAPOLICE.FR/POST_5",
        "WWW.JESOUTIENSLAPOLICE.FR/POST_6"
]

*/

As usual, I've uploaded it to a gist.

Friday 12 August 2022

Python Descriptors

Properties (aka getters-setters) in python do not seem like any particularly "advanced" feature. In principle it's just adding a getter and setter method to access a given attribute. Well, properties are a specific case of descriptors. In short a descriptor is an object with a __get__ method, and optionally __set__ and __delete__ methods. Adding a property to a class is not just directly adding a getter (setter, deleter) method to the class, it's adding an object that is an instance of the property class. There's a very nice explanation here

descriptors are a low-level mechanism that lets you hook into an object's attributes being accessed. Properties are a high-level application of this; that is, properties are implemented using descriptors. Or, better yet, properties are descriptors that are already provided for you in the standard library.

When we do an attribute lookup on an object and the found attribute is a descriptor (and it finds it in the class of that object, not directly in the object.__dict__) the runtime invokes its __get__ method (or __set__ or __delete__). Yes, descriptor objects have to be in the class, not directly in the instance, you can read an explanation here

What is really interesting of descriptors is that they are used to implement much of the python behaviour we like so much. For example, I used to think that in order to return a bound method when you access a method from an instance the python runtime would have some very specific code for that. A function (something that we define with "def" or "lambda") is an instance of the function class, that happens to be a descriptor. When we define a method in a class, we are adding that function object to that class __dict__. So when invoke that method in an instance (my_instance.method1("aaa")), we are first looking up the "method1" attribute in the my_instance object. It will be found in the __dict__ of my_instance class, and as it has a __get__ method (and has not been found directly in my_instance), that __get__ method is executed, and it takes care of returning an object that is an instance of the method class, bound to my_instance (and finally, for the call itself, the ("aaa") part, as the retrieved object is callable, __call__ method in the method class is invoked) So we have a language feature that is not implemented by some specific runtime/interpreter code, but just using a standard python feature.

The python documentation about descriptors is really, really good, as it helps you understand pretty important elements of the language, like attribute lookup, bound methods, class methods (a decorator applied to a function descriptor)... It provides python implementations of these functionalities, so it's really worth a read.

Attribute look-up is implemented in object.__getattribute__ and type.__getattribute__. When looking up an attribute of an object, the runtime searches for the __getattribute__ method in that object's class. So for an instance of a "normal class" (let's say an instance p1 of class Person:, p1.instance_attribute) the runtime searches for __getattribute__ in Person.__dict__, where unless that we have redefined it for the class, it won't find it, so it will continue to search in the inheritance chain and will end up finding it in object.__dict__["__getattribute__"]. If we are looking up an attribute in a class itself (Person.my_class_attribute), it will search in Person's class, that is either type or a class derived from type (if Person were using another metaclass (I mean: class Person(metaclass=CustomMetaclass):). So we'll end up with type.__dict__["__getattribute__"].
If the __getattribute__ that we've executed finds a descriptor, the invocation of __get__ in that descriptor is done with: desc.__get__(a, type(a)) from the object.__getattribute__, and with: desc.__get__(None, A) from the type.__getattribute__.

When you check the class of an object using the __class__ attribute, it's also implemented as a descriptor (same as __name__, as I already mentioned here), so __class__ is not in the object dictionary, but in the class, particularly in its inheritance chain, in object.__dict__['__class__']. There's a good explanation here

It's interesting that properties are implemented to match the behaviour of object.__getattribute__ and type.__getattribute__ so that when accessing a property from an instance we obtain the value, while accessing it from the class returns the proprerty object.


In [70]: class Book:
    ...:     @property
    ...:     def price(self):
    ...:         return 4
    ...:         

In [71]: b1 = Book()

In [72]: b1.price
Out[72]: 4


In [74]: b1.__class__.__dict__["price"]
Out[74]: <property> at 0x1c31f647ce0>

In [75]: b1.__class__.price
Out[75]: <property> at 0x1c31f647ce0>

This is a bit different in JavaScript, a language that also has the concept of descriptors (they are used for any attribute, not just for getters-setters aka "access descriptors"), but where to get the descriptor object rather than the value, we have to use a specific method: Object.getOwnPropertyDescriptor


class Person{
    constructor(name, lastName){
        this.name = name;
        this.lastName = lastName;
    }

    get fullName(){
        return `${this.name} ${this.lastName}`; 
    }

    sayHi(toX){
        return `Hi ${toX} I am ${this.name}`
    }

}

let p1 = new Person("Francois", "Belmondo")
console.log(p1.fullName); //Francois Belmondo

// the fullName access descriptor is in Person.prototype (just as the sayHi function)
//these 2 execute the "getter", but with the Person.prototype as "this", so gets undefined name and lastName
console.log(Person.prototype.sayHi("aa")); //Hi aa I am undefined
console.log(Person.prototype.fullName); //undefined undefined

let d1 = Object.getOwnPropertyDescriptor(Person.prototype, "fullName"); //the descriptor

let d2 = Object.getOwnPropertyDescriptor(p1, "fullName"); // undefined
let d3 = Object.getOwnPropertyDescriptor(Person, "fullName"); //undefined


Sunday 7 August 2022

Young Ahmed

Last Saturday Tve2 gifted us with the screening of the absolutely excellent Belgian film Young Ahmed - Le jeuene Ahmed. In my opinion Belgium is the European country where the Muslim invasion and the process of replacement of the European culture by a hostile and less evolved (in moral terms, in terms of achievements, etc) culture is in its most advanced stage. Well, I think it's worse than in France in terms of percentages, though in France the invaders are even more hostile, cause they are motivated not only by their interpretation of religion and by their racist (anti-white and anti-EastAsian racism) and ultranationalist "culture" but also by the colonial hatred and that senseless victimization feeling that the far-left (from Sartre to Melenchon) has instilled on them for the last decades.

Ahmed is a 13 years old teenager of maghrebian descent that gets radicalised by his Imam to a level that you can only believe if you've experience the failed multicultural experience of countries like France or Belgium, otherwise you would think that such level of hatred and fanatism can not exist in our century. I appreciate a lot the bold and realistic stance of the directors, that do not try to find any sort of justification for this madness. The guy's family does not live in poverty and is not a victim of "discrimination" from the evil "white Belgians". The mother is a well integrated woman that behaves and looks like a normal person (I don't ask immigrants to become exemplary citizens, I just ask them to be normal people (with "normal" being based on the standards of our European culture) that just wants the best for her kids, and his sister looks also totally normal, but his brother seems to be starting to move to the wrong side. There was a cousin that died as a yihadist, that is a dishonor for the mother, but a role-model for this Ahmed scumbag.

This film shows us fundamentalist Islam in all its cruelty. A teenager that refuses to shake hands with his teacher (that had become a family friend after much helping him years ago with different problems), because she is a woman. She is a working woman of Muslim descent, well integrated (and we can guess that she still considers herself a Muslim, as she tries to explain to Ahmed that her Coran does not say what his Imam is teaching him), that because of that is no longer considered a Muslim by the Imam or Ahmed, but an apostate (yes, if you are not as radical as us, you are no longer a Muslim). Strict (or fundamentalist, I'm not sure what term to use) interpretations of Islam consider Apostasy to be punishable by death... so well, Ahmed brings yihad home by trying to kill this brave woman!!!

This film shows 2 essential elements of radical Islam without directly naming/explaining them. The first one is the fundamentalist interpretation of Taqiya. Allegedly, Taqiya means that Muslims can dissimulate their faith (or just lie, saying that they are not Muslims) to save their lives. Fundamentalist views consider that you can (and must) lie to protect and spread Islam. So Ahmed lies all the time, saying that his Imam has nothing to do with his radical views, that he regrets his actions and wants to ask for forgiveness to his teacher...
The second essential element is salvation through yihad. When Ahmed considers to have committed a terrible sin (he has kissed a girl!!!) he goes like crazy in a new attempt to kill his teacher, as this action to "protect" Islam will clean his sins and save him. This view is the basis of how many drug dealers and criminals of "muslim culture" suddenly get radicalised and become yihadists/terrorists. After doing wrong things for years, now you kill and die in the name of God and all your sins get cleaned and you go to heaven to enjoy your well deserved Harem... cool...

An additional point of interest is that after having sinned (kissing that girl!!!) Ahmed first tries to convert her to Islam to marry him (buff, that's love at first sight), because that way his sin could be forbidden (I guess it's not just that kissing a Muslim is not so bad as kissing an infidel, it's that if you are converting her you are spreading the faith, so that earns you points). As she rejects such a beautiful proposal and prefers to remain a Kuffar, the only way to salvation, as I've just mentioned in the previous paragraph, is doing "something big", like killing an apostate.

To sum up, a true must-see film.

Thursday 28 July 2022

functools Partial and __name__

I've recently come across a small issue with python functools and a simple solution. First, let's start with some theory.

You can get the name of a class by means of __name__. Maybe you think that's an attribute of the class (I mean, given a class Person, you could think that you have the __name__ attribute in Person.__dict__). That's wrong. __name__ is a descriptor in Person.__class__ (Person's metaclass), hence, a descriptor in Person.__class__.__dict__. Notice that if __name__ were directly an attribute in the class, you could do person_instance.__name__, something that is not possible


class Person:
	pass
Person.__name__
Out[52]: 'Person'

Person.__dict__["__name__"]
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Input In [53], in ()
----> 1 Person.__dict__["__name__"]

KeyError: '__name__'

Person.__class__.__dict__["__name__"]
Out[54]: <attribute '__name__' of 'type' objects>

type(Person.__class__.__dict__["__name__"])
Out[55]: getset_descriptor

p1 = Person()

p1.__name__
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Input In [57], in ()
----> 1 p1.__name__

AttributeError: 'Person' object has no attribute '__name__'

You can also get the __name__ of a function. Again, this is not an attribute directly in each function dictionary, but a descriptor in the function's __class__.__dict__. Python functions are objects that are instances of the class "function", so it's interesting how instances of the function class has a __name__, by means of the __dict__[__name__] in the function class, but as we've seen above, a normal class like Person does not have such __name__ in its own __dict__.


def say_hi(who):
    print(f"hi {who}")
    

say_hi.__name__
Out[60]: 'say_hi'

say_hi.__dict__["__name__"]
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Input In [61], in ()
----> 1 say_hi.__dict__["__name__"]

KeyError: '__name__'

say_hi.__class__.__dict__["__name__"]
Out[62]: <

The functools module provides us with all (or most) "functional helper" functions that we can be used to from other languages. functools.partial is used to create partially applied funtions, so it's similar to JavaScript Function.prototype.bind. Interestingly, functions.partial does not return another function (a closure trapping the parameters being bound and the original function itself), but an instance of the functools.partial class (as such class has a __call__ method, that instance is callable and is mainly like a function to us). The problem I've found with that partial object is that it lacks a __name__ attribute.


def format_message(wrap_str, msg):
    return f"{wrap_str}{msg}{wrap_str}"

format_with_x = functools.partial(format_message, "x")
print(format_with_x("Hi"))

print(type(format_message))
print(format_message.__name__)

print(type(format_with_x))
try:
    print(format_with_x.__name__)
except BaseException as ex:
    print(f"Exception: {ex}")

# xHix
# <class 'function'>
# format_message
# <class 'functools.partial'>
# Exception: 'functools.partial' object has no attribute '__name__'


I've found here that functools provides a fix for this, the functools.updatewrapper function, that "Updates a wrapper function to look like the wrapped function". This means that we can just do this:


def create_wrapped_partial(func, *args, **kwargs):
    partial_func = functools.partial(func, *args, **kwargs)
    functools.update_wrapper(partial_func, func)
    return partial_func
	
format_with_z = create_wrapped_partial(format_message, "z")
print(format_with_z("Hi"))
print(type(format_with_z))
try:
    print(format_with_z.__name__)
except BaseException as ex:
    print(f"Exception: {ex}")
	
# zHiz
# <class 'function'>
# format_message
# <class 'functools.partial'>
# format_message	

Friday 22 July 2022

Run Function with Timeout

I've recently needed to be able to stop a function if it had not finished after a timeout period. I'm not talking about an eventloop and an asynchronous function returning an awaitable in Python (or a Promise in Javascript). Indeed, years ago I already posted about expirable promises in JavaScript. What I'm talking about is a synchronous Python function (normally doing some CPU bound calculation) that we want to stop if it has not finished after a given amount of time. I say stop its operation, not just stop waiting for it but let it run in the background uselessly consuming resources.

A solution that easily comes to mind is running the function in a separate Thread and joining that thread with the timeout option. If the timeout expires our calling code will stop blocking and continue on, but the problem is that the thread doing that costly CPU operation will continue to run and we have no way to kill it. This is something that really bothers me. Neither Python, nor .Net nor Java let you kill a thread "from outside" (I mean from another thread, what is still possible I think is killing the thread you are running in). I know that the reason for discouraging and not providing this functionality is that when you kill another thread it could be holding resources or doing something critical and killing it could mess things...) OK, but we are grown ups, so if you know that such thread can be killed withoug causing problems, you should be allowed... Well, anyway...

In order to overcome the limitations imposed by the GIL to parallelism, python provides an extremely powerful library to run your code in separate processes as easily as you run it in separate threads in other platforms: multiprocessing (and the higher level ProcessPoolExecutor in concurrent.futures). Contrary to threads, you are allowed to kill (terminate) processes, so I've implemented the timeout functionality running the function in a separate process.

So I have a create_func_with_timeout factory function, that receives a function fn and a timeout value and returns a new function that takes care or running fn in a separate process, waiting for it for a timeout time and throwing a TimeoutException if it expires. If fn itself were to throw an exception we want to have it available in the calling process, so to manage this we wrap the execution of fn in the mp_function_wrapper function. This function returns to the calling process the normal result of running fn (or an exception it that were the case) by writing it to a multiprocessing queue.

Reading the code should make it clear:


import multiprocessing
import queue
import threading
from time import sleep
from typing import Any, Dict, TextIO, List, Callable, Tuple, Optional, AnyStr, Match, cast


class TimeoutException(Exception):
    pass

def create_func_with_timeout(fn: Callable, timeout: int) -> Callable:
    """
    returns a new function that runs the provided fn in a separate process that either finishes normally or times out
    """
    def mp_function_wrapper(fn: Callable, queue: multiprocessing.Queue, *args, **kwargs):
        """
        this function has been started in a separate process
        it "returns" the result of fn to the main process by writing it to the queue
		we could take fn and timeout as closure values, but it seems more clear to pass them as parameters
        """
        try:
            result = fn(*args, **kwargs)
        except BaseException as ex:
            result = ex
        queue.put(result)
        
    def func_with_timeout(*args, **kwargs):
        """
        has the fn to run trapped as closure value
        """
        try:
            multiprocessing.set_start_method('fork')
            # multiprocessing.set_start_method('spawn')
        except RuntimeError as ex:
            print(f"set_start_method: {ex}")
        print(f"func_with_timeout {fn.__name__} {timeout}")
        response_queue = multiprocessing.Queue()
        extended_args = [fn, response_queue, *args]
        proc = multiprocessing.Process(target=mp_function_wrapper, args=extended_args, kwargs=kwargs)
        proc.start()
        try:
            result = response_queue.get(block=True, timeout=timeout)
        except queue.Empty:
            # the process is still running, so finish it off
            proc.terminate()
            raise TimeoutException()
        if result and isinstance(result, BaseException):
            raise result
        return result
  
    return func_with_timeout


def format_items(items):
    #print(f"format_items")
    results = []
    for item in items:
        sleep(1)
        results.append(item.upper())
        #print(item)
    return ",".join(results)

format_with_timeout = create_func_with_timeout(format_items, 5)

def run_test(items):
    print("- test")
    try:
        res = format_with_timeout(items)
        print(f"result: {res}")
    except BaseException as ex:
        print(f"exception: {type(ex).__name__} {ex}")


print("- starting")

run_test(["a", "b", "c"])

run_test(["a", "b", "c", "d", "e", "f", "g"])

run_test(["a", None])

print("- ending")

# - starting
# - test
# format_items
# result: A,B,C
# - test
# format_items
# exception: TimeoutException
# - test
# format_items
# exception: AttributeError 'NoneType' object has no attribute 'upper'
# - ending


I've also uploaded it to a gist