Metadata-Version: 2.1
Name: cursed-for
Version: 0.3.0
Summary: Adding C-style for loops to Python.
Home-page: https://github.com/tusharsadhwani/cursed-for
Author: Tushar Sadhwani
Author-email: tushar.sadhwani000@gmail.com
License: MIT
Platform: UNKNOWN
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Typing :: Typed
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: black ; extra == 'dev'
Requires-Dist: mypy ; extra == 'dev'
Requires-Dist: pytest ; extra == 'dev'
Requires-Dist: pytest-cov ; extra == 'dev'
Requires-Dist: tox ; extra == 'dev'

# cursed-for

Adding C-style for loops to Python, because you can.

```pycon
>>> for (i = 0; i < 10; i += 2):
...     print(i)
0
2
4
6
8
```

## Installation

```text
pip install cursed-for
```

## Usage

Add the following `# coding` comment at the top of the file in which you wish to
curse:

```python
# coding: cursed_for
```

Then write the cursed for-loops as needed. Check [this file][ex] for an example.

For an interactive REPL, type `cursed-for` in your terminal:

```console
$ cursed-for
Cursed Python REPL, 3.10.4 (main, Apr  2 2022, 09:04:19) [GCC 11.2.0]
>>> x = 10
>>> for (;x > 5;x -= 3):
...     print(x)
10
7
```

## But why?

This was made because of a cursed idea I had one night, which I put on
[twitter](https://twitter.com/sadhlife/status/1497501076589019139):

<p align="center">
  <img src="https://user-images.githubusercontent.com/43412083/173145281-1a63ad93-56c0-4fd0-b8f1-78e7bf7005d6.png" width="500">
</p>

And although this worked, I didn't like the look of it. But using the methods I
used, I was confined by Python's syntax, which really doesn't support the kind
of things I'd have liked to do. But then I stumbled upon a [couple][1] of
[packages][2] which gave me exactly the tools I needed to commit this atrocity.

## OK, but how is this possible?

I wrote a [blog][blog] on the approaches I went through to implement this.

The rough iterations that happened during the development are documented in the
[approach folder][3]. It contains both the AST manipulation method, and
the "truly cursed" method.

## The "old way" usage

The first version (as shown in the original tweet) is also present in the
repository, for archival purposes.

Note that this only really works in a REPL. To start it, run [cursedfor.py][4]
in the terminal. It's a single file, you can get it by just downloading the one
file if you want to.

```pycon
>>> with _for(i := 0, i < 10, i += 2):
...     print(i)
0
2
4
6
8
```

## Help, something is broken!

You can use the `cursed-for-decode` command to figure out what code is being
generated by the module:

```console
$ cat x.py                                                  
for (i = 1; i < 100; i += 1):
    print(i)

$ cursed-for-decode x.py
i = 1
while i < 100:
    print(i)
    i += 1
```

If the generated code seems wrong, [file a bug report][issue] with the code
snippet.

[1]: https://pypi.org/p/cstyle
[2]: https://github.com/asottile/future-fstrings
[3]: https://github.com/tusharsadhwani/cursed-for/approach
[4]: https://github.com/tusharsadhwani/cursed-for/approach/ast_manipulation/cursedfor.py
[ex]: https://github.com/tusharsadhwani/cursed-for/approach/the_truly_cursed_way/test_v3.py
[blog]: https://sadh.life/post/cursed-for
[issue]: https://github.com/tusharsadhwani/cursed-for/issues/new


