Using LLMs to create a python library

Using LLMs to create a python library

I have used Gemini and Claude LLM models to create a mypy plugin to mark a function as pure: mypy-pure.

Introduction

I think that static analysis in Python is a great opportunity to catch a lot of issues before running the program.

I do not even remember when, but I saw a thread in the Python official forum where a user was suggesting this @pure decorator idea to the Steering Council of Python.

The idea got lost in the conversation, the pros, the cons, etc. But I liked the idea and got me thinking.

The idea

Some weeks ago I asked ChatGPT about creating an empty decorator in Python (@pure), and using it to mark the functions in a special way. It showed me some code that I copied, studied and understood (The AST visitors are not the easiest part of the standard Python library).

My idea was to leverage mypy, and check that if the function had the @pure decorator, it could not call to functions that were not pure.

I know that pure functions apart from not having side-effects, must return the same value for the same inputs, but I decided to ignore that part because it was going to be difficult to check that statically. On the other hand, checking if a function had side-effects was relatively easy, as we only need to check if a function calls a subset of impure functions of the Python standard library.

Anyhow, I abandoned the idea because I did not have time, and was not even sure about the usefulness of this functionality.

The final push

Google had released Antigravity, a new and shiny editor with AI agent integration, and a generous free tier. I thought to myself, could I implement this library by leveraging LLMs capabilities?

The development

I decided to spend two hours each day having a conversation with a LLM I started seeing results.

The first day I had a decorator that was able to detect if a function was calling an impure function directly.

The next day I was able to check if any of the ancestor called functions by a function was impure.

In 4 days I had the 0.2.1 with support for:

Support for marking as @pure functions:

  • Properties (@property)
  • Instance methods
  • Class methods (@classmethod)
  • Static methods (@staticmethod)
  • Async functions (async def)
  • Async methods
  • Nested/inner functions

Blacklisted standard functions (impure): 230+ impure functions including:

  • All major stdlib modules (logging, threading, multiprocessing, signal, etc.)
  • Network operations (http.client, urllib, ftplib, smtplib, etc.)
  • Database operations (sqlite3, dbm, shelve)
  • File operations (tempfile, pickle, pathlib)
  • System operations (gc, warnings, atexit)

The released product

At the end of the day, I have an useful library that can detect use of functions with side-effects when running mypy on your code.

Install the library from pypi.

pip install mypy-pure

Enable the plugin in your mypy configuration

In your mypy.ini or pyproject.toml add mypy_pure to your list of plugins:

[mypy]
plugins = mypy_pure.plugin

Add a list of your known pure impure functions to your mypy.ini or pyproject.toml

In your mypy.ini or pyproject.toml you can optionally define a list of impure or pure functions.

[mypy-pure]
# Blacklist your impure functions
impure_functions = my_module.send_email, my_module.log_event

# Whitelist pure third-party functions
pure_functions = requests.utils.quote, requests.utils.unquote

Use the @pure decorator on your functions

from mypy_pure import pure

@pure
def calculate_total(prices: list[float], tax_rate: float) -> float:
    subtotal = sum(prices)
    return subtotal * (1 + tax_rate)

Caveats

The LLM will always try to take the easiest step

Yes, the LLMs are lazy and tend to remove, and ignore complete pieces of code.

You need to navigate the conversation

Sometimes, the LLMs hallucinate or worse, they propose removing features that clash with their view. You need to be at the helm of the process, so in every change they propose, you can steer their actions to what you actually want.

And everything of that without taking in account proposals that, while being

There is no agreement on what the license could be for that code

I even asked Reddit about this!

Some people say that the LLMs memorize code with different license, hence producing some pieces of code that came from projects with incompatible licenses.

To be fair, I think that we have reached the point of practicality, and assumed that the LLMs just read everything and just adjust their weights from all they get their hands on.

I have not seen any regurgitated piece of code, but that is what they say.

My project has the MIT license and I will defend it arguing:

Conclusion

The development velocity with LLMs is surprising: what could have been 1 month of development was done by the LLM and checked by me, in hours.

The legality of the code still seems to be an issue.

llm  ai  war-story