cqfn / pdd

Command line toolkit for collecting TODO markers from your code, known as Puzzle Driven Development (PDD)
https://www.0pdd.com
MIT License
77 stars 26 forks source link

Significant trailing whitespace for puzzle description. #242

Open proofit404 opened 4 days ago

proofit404 commented 4 days ago

Hello! Thank you for amazing development approach and automation tool for it!

I have a complicated puzzle like this

# ~ @todo #7 Engine objects.
# ~
# ~ To my understanding we have to introduce `Engine`, `Connection`, or
# ~ `Driver` objects. The main reiquirement for this architecture
# ~ decision that we have to unify different `execute`, `fetch`,
# ~ `fetch_many`, and `cursor` APIs to use them inside `Sql` object.
# ~
# ~ We have different options here.
# ~
# ~ We can use `encode/databases` which already did this work for
# ~ us. My main concern is that I have a plan to support Django query
# ~ builder as well, but this project was built on top of SQLAlchemy
# ~ and has it as install requirement. Running queries built with
# ~ Django inside active SQLAlchemy connection pull using two packages
# ~ to abstract it out is a clusterfuck decission.
# ~
# ~ Another concern is that it would tight us to the asynchronous
# ~ world. And this is as bad as building this library on top of
# ~ SQLAlchemy engine system throwing away both SQLAlchemy ORM and
# ~ SQLAlchemy Core.
# ~
# ~ On the other side I don't want to abstract `asyncpg` and `mysql`
# ~ libraries into a single object. It would highly increase possibilty
# ~ of problems in the future and force us to expand it's public
# ~ interface each time. Also, due to database differencies each method
# ~ of same (but broad) interface would be slightly differnt behavior.
# ~
# ~ Also, I really don't want to tight `Sql` object inheritance to the
# ~ actually used engine. It 100% should be late binding. So, nothing
# ~ even close to passing engine instance into table definition Meta
# ~ options.
# ~
# ~ The core consept is that we SHOULD NOT OWN `asyncpg.Connection` ~
# ~ instance inside our engine object. Most sertainly would would have
# ~ `Connection` abstract class, a concrete driver adapter for each ~
# ~ supported library.
# ~
# ~ ```pycon
# ~ >>> import asyncpg
# ~ >>> import typedsql
# ~ >>> connection = await asyncpg.connect(user='user', password='password', database='database', host='127.0.0.1')
# ~ >>> typedsql.guess_adapter(connection)
# ~ AsyncpgAdapter()
# ~ ```

It produces this puzzle:

  <puzzle>
    <ticket>7</ticket>
    <estimate>0</estimate>
    <role>DEV</role>
    <id>7-a569c937</id>
    <lines>37-37</lines>
    <body>Engine objects.</body>
    <file>src/typedsql.py</file>
  </puzzle>

Which is far from being correct. However, if I replace # ~ lines in my code to # ~ it will produce correct result.

 # ~ @todo #7 Engine objects.
-# ~
+# ~ 
 # ~ To my understanding we have to introduce `Engine`, `Connection`, or
 # ~ `Driver` objects. The main reiquirement for this architecture
 # ~ decision that we have to unify different `execute`, `fetch`,
 # ~ `fetch_many`, and `cursor` APIs to use them inside `Sql` object.
-# ~
+# ~ 
 # ~ We have different options here.
-# ~
+# ~ 
 # ~ We can use `encode/databases` which already did this work for
 # ~ us. My main concern is that I have a plan to support Django query
 # ~ builder as well, but this project was built on top of SQLAlchemy
 # ~ and has it as install requirement. Running queries built with
 # ~ Django inside active SQLAlchemy connection pull using two packages
 # ~ to abstract it out is a clusterfuck decission.
-# ~
+# ~ 
 # ~ Another concern is that it would tight us to the asynchronous
 # ~ world. And this is as bad as building this library on top of
 # ~ SQLAlchemy engine system throwing away both SQLAlchemy ORM and
 # ~ SQLAlchemy Core.
-# ~
+# ~ 
 # ~ On the other side I don't want to abstract `asyncpg` and `mysql`
 # ~ libraries into a single object. It would highly increase possibilty
 # ~ of problems in the future and force us to expand it's public
 # ~ interface each time. Also, due to database differencies each method
 # ~ of same (but broad) interface would be slightly differnt behavior.
-# ~
+# ~ 
 # ~ Also, I really don't want to tight `Sql` object inheritance to the
 # ~ actually used engine. It 100% should be late binding. So, nothing
 # ~ even close to passing engine instance into table definition Meta
 # ~ options.
-# ~
+# ~ 
 # ~ The core consept is that we SHOULD NOT OWN `asyncpg.Connection` ~
 # ~ instance inside our engine object. Most sertainly would would have
 # ~ `Connection` abstract class, a concrete driver adapter for each ~
 # ~ supported library.
-# ~
+# ~ 
 # ~ ```pycon
 # ~ >>> import asyncpg
 # ~ >>> import typedsql
  <puzzle>
    <ticket>7</ticket>
    <estimate>0</estimate>
    <role>DEV</role>
    <id>7-c90065bd</id>
    <lines>37-80</lines>
    <body>Engine objects. To my understanding we have to introduce `Engine`, `Connection`, or `Driver` objects. The main reiquirement for this architecture decision that we have to unify different `execute`, `fetch`, `fetch_many`, and `cursor` APIs to use them inside `Sql` object. We have different options here. We can use `encode/databases` which already did this work for us. My main concern is that I have a plan to support Django query builder as well, but this project was built on top of SQLAlchemy and has it as install requirement. Running queries built with Django inside active SQLAlchemy connection pull using two packages to abstract it out is a clusterfuck decission. Another concern is that it would tight us to the asynchronous world. And this is as bad as building this library on top of SQLAlchemy engine system throwing away both SQLAlchemy ORM and SQLAlchemy Core. On the other side I don't want to abstract `asyncpg` and `mysql` libraries into a single object. It would highly increase possibilty of problems in the future and force us to expand it's public interface each time. Also, due to database differencies each method of same (but broad) interface would be slightly differnt behavior. Also, I really don't want to tight `Sql` object inheritance to the actually used engine. It 100% should be late binding. So, nothing even close to passing engine instance into table definition Meta options. The core consept is that we SHOULD NOT OWN `asyncpg.Connection` ~ instance inside our engine object. Most sertainly would would have `Connection` abstract class, a concrete driver adapter for each ~ supported library. ```pycon &gt;&gt;&gt; import asyncpg &gt;&gt;&gt; import typedsql &gt;&gt;&gt; connection = await asyncpg.connect(user='user', password='password', database='database', host='127.0.0.1') &gt;&gt;&gt; typedsql.guess_adapter(connection) AsyncpgAdapter() ```</body>
    <file>src/typedsql.py</file>
  </puzzle>

This is error prone and misleading. It requires extra attention. Many code editors and IDEs remove trailing white space automatically. Which force you to fight with your tools.

Thoughts?

php-coder commented 3 days ago

Hi, I agree with you and I've already raised that concern some time ago: https://github.com/cqfn/pdd/pull/237#discussion_r1461361078