moskytw / mosql

Build SQL with native Python data structure smoothly.
http://mosql.mosky.tw
MIT License
140 stars 17 forks source link

help not really help for insert, delete, select ,, etc. #20

Closed lucemia closed 10 years ago

lucemia commented 11 years ago
>>> from mosql import query
>>> help(query.insert)

Help on Query in module mosql.util object:

class Query(__builtin__.object)
 |  It makes a partial :class:`Statement`.
 |  
 |  :param statement: a statement
 |  :type statement: :class:`Statement`
 |  :param positional_keys: the positional arguments accepted by :meth:`stringify`.
 |  :type positional_keys: sequence
 |  :param clause_args: the arguments of the clauses you want to predefine
 |  :type clause_args: dict
 |  
 |  .. versionadded :: 0.6
 |  
 |  Methods defined here:
 |  
 |  __call__(self, *positional_values, **clause_args)
 |      It is same as the :meth:`stringify`. It is for backward-compatibility, and not encourage to use.
 |  
 |  __init__(self, statement, positional_keys=None, clause_args=None)
 |  
 |  __repr__(self)
 |  
 |  breed(self, clause_args=None)
 |      It merges the `clause_args` from both this instance and the argument,
 |      and then create new :class:`Query` instance by that.
...

it will be helpful if

>>> help(select)

mosql.query.select(table=None, where=None, **clause_args)

It generates the SQL statement, SELECT ... .
The following usages generate the same SQL statement.
moskytw commented 11 years ago

It will be hard to fix, because the insert, select, ... actually are the instances of Query, so the document is written in Sphinx rather than in theirs docstring. You can check the query.rst which is the source of this page and query.py for detail.

It will be nice if you have idea to fix it.

uranusjr commented 11 years ago

I've had some thought on this too, since mosql's current implementation doesn't play well with bpython and CodeIntel, either. One of the quick 'n' dirty solution I've come up with is (in query.py)

def select(table=None, where=None, **clause_args):
    """docstring goes here"""
    return Query(statement.select, ('table', 'set'))(table, where, **clause_args)

Not pretty, but gets the job done.

moskytw commented 11 years ago

I believe you are kidding me. LOL

uranusjr commented 11 years ago

Partly, but there isn't really a good solution, is there? :p

Seriously though, the only solution (other than the above one if it can be called that way) I can think of is using metaclass. But Python 2 and 3 have different metaclass syntaxes, and it would cause incompatibility beyond repair.

Bottom line is, it would be really nice to have some kind of inline documentation available, and (personally) I would do some ugly things to get it.

moskytw commented 11 years ago

I won't do so. It is too over to hack the original code just for supporting doc. And we already have the http://mosql.mosky.tw/query.html . :)

lucemia commented 11 years ago

I tried to hack the docstring but still got nothing. I guess there is no good way to do so for now (as far as I know). and the Issue can be marked as Wont Fix for now. BTW I think @uranusjr provide a possible way, since the interface don't need to expose the implementation.

eugene-eeo commented 10 years ago

Just modify the doc attribute of the function.

eugene-eeo commented 10 years ago

Sorry, I mean to use __doc__.

uranusjr commented 10 years ago

Setting __doc__ gets you nowhere, unfortunately. Things like mosql.query.insert are implemented as callable instances, and help generates its content by the docstring of their class, which is mosql.util.Query. Run the following and you'll see the problem:

class Foo(object):
    """An example class
    """

foo = Foo()
foo.__doc__ = 'This is an instance'
help(foo)

With that said, you actually got me thinking again. Metaclassing should work:


class BaseFoo(object):
    """An example class
    """

def get_foo(docstring):

    class MetaFoo(type):
        def __new__(cls, name, parents, attrs):
            attrs['__doc__'] = docstring
            return super(MetaFoo, cls).__new__(cls, name, parents, attrs)

    class Foo(object):
        __metaclass__ = MetaFoo

foo = get_foo()
help(foo)

But this stills seems pretty hacky to me, to be honest.

eugene-eeo commented 10 years ago

Make a constructor for the class that does the same thing, assign insert to that constructor and document it.

moskytw commented 10 years ago

Could you give an example? I didn't understand.

moskytw commented 10 years ago

I am going to close this issue. I will refine the Sphinx docs.