semvec/pypi-packages huggingface dataset:
il 0.3
Inline assembly in Python

# il - inline assembly in Python 3

Examples
--------

1. Decorator API - simple

```python
import il
import ctypes

@il.asm
def add_ints(rdi=ctypes.c_int32, rsi=ctypes.c_int32):
    """
    # return sum of two 32-bit integers
    # 64-bit Linux/MacOS call convention
    #
    .intel_syntax noprefix
    mov rax, 0
    mov eax, edi
    add eax, esi
    ret
    """
    return ctypes.c_int32

print(add_ints(43, -1))
```

2. Function API - powerful

```python
add_ints = il.def_asm(
     name="add_ints",
     prototype=ctypes.CFUNCTYPE(ctypes.c_int32,  # return value (eax)
                                ctypes.c_int32,  # 1st param (edi)
                                ctypes.c_int32), # 2nd param (esi)
     code="""
     .intel_syntax noprefix
     mov rax, 0
     mov eax, edi
     add eax, esi
     ret
     """)

print(add_ints(43, -1))
```

Dependencies
------------

- If object code is available: no dependencies outside Python standard
  library. `ctypes` from the standard library is needed for loading
  and running object code.

- If object code is not available: `as` and `objcopy` (from
  `binutils`) are required for compiling assembly.

Install
-------

```sh
$ sudo python3 setup.py install
```

Library API documentation and call conventions
----------------------------------------------

```sh
$ python3 -c 'import il; help(il)'
```

How it works
------------

- Assume that `mylib.py` contains inlined assembly. By default, `il`
  looks for object code from `mylib.py.il`. If found, that code will
  be executed when inlined functions are called.

- If object code is not found, `il` uses binutils: `as` (assembler)
  and `objcopy` to compile the assembly on-the-fly and extract object
  code from the result. Object code is saved to `mylib.py.il` for
  later use.

- Note: `il` does not link object code before running it.

- You can view contents of `mylib.py.il` using `il`:
  ```sh
  $ python3 -c 'import il; print(il.dump_lib("mylib.py.il", disasm=False))'
  ```
  (Use `disasm=True` to disassemble the code in the dump. Requires `objdump`.)

Debugging inlined assembly
--------------------------

1. Import the library, print the pid of the Python process and the
   address of the function that you want to debug:
   ```python
   >>> import mylib
   >>> import os
   >>> os.getpid()
   12345
   >>> print(mylib.myfunc.il_addr)
   21954560
   ```

2. Attach GDB to the Python process, set a breakpoint to the address
   and let the Python process continue.
   ```bash
   $ gdb -p 12345
   (gdb) layout asm
   (gdb) break *21954560
   (gdb) cont
   ```

3. Call the function in Python
   ```python
   >>> mylib.myfunc()
   ```

4. Now you can step assembly instructions and see register values in
   GDB:

   ```bash
   (gdb) ni
   (gdb) info registers
   ```
aio-throttle-to-next-second 0.0.1
Throttler for asyncio Python that throttles to the next whole second
Requires Python: ~=3.5

# aio-throttle-to-next-second [![CircleCI](https://circleci.com/gh/uktrade/aio-throttle-to-next-second.svg?style=svg)](https://circleci.com/gh/uktrade/aio-throttle-to-next-second) [![Test Coverage](https://api.codeclimate.com/v1/badges/e791b8d7273920821a9a/test_coverage)](https://codeclimate.com/github/uktrade/aio-throttle-to-next-second/test_coverage)

Throttler for asyncio Python that throttles to the next whole second, as reported by `time.time()`. This is useful to force an order on requests to a service that uses a "latest timestamp wins" strategy, such as S3.


## Installation

```bash
pip install aio-throttle-to-next-second
```


## Usage

Create a shared `Throttler`, with no arguments

```python
from aio_throttle_to_next_second import Throttler

throttler = Throttler()
```

and then just before the piece(s) of code to be throttled, _call_ this and `await` its result.

```python
await throttler()
# Each execution reaching this line will reach this line at a different second
```


## Example: multiple tasks throttled

```python
import asyncio
import time

from aio_throttle_to_next_second import Throttler

async def main():
    throttler = Throttler()
    await asyncio.gather(*[
        worker(throttler) for _ in range(10)
    ])

async def worker(throttler):
    await throttler()
    # Each print will show a distinct second, though all workers started together
    print(int(time.time()))

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
```


## Example: single task throttled

```python
import asyncio
import random
import time

from aio_throttle_to_next_second import Throttler

async def main():
    throttler = Throttler()
    for _ in range(10):
        await throttler()
        # Each print will show a distinct second, though there is a random sleep
        print(int(time.time()))
        await asyncio.sleep(random.random())

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
```