From b0f06f7e52c8587290bed055e62f5e6efa26ec04 Mon Sep 17 00:00:00 2001 From: "P. Christeas" Date: Thu, 23 Jun 2011 12:02:28 +0300 Subject: [PATCH] orm, tools, addons: Doc strings improvements bzr revid: xrg@linux.gr-20110623090228-4gn6xoyykcvfhv13 --- openerp/osv/fields.py | 40 ++++++++++++++++-------- openerp/osv/orm.py | 71 +++++++++++++++++++++++++++---------------- openerp/tools/misc.py | 64 +++++++++++++++++++++----------------- 3 files changed, 109 insertions(+), 66 deletions(-) diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index f55e4b9c027..54d1d1dae6b 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -19,18 +19,19 @@ # ############################################################################## -# . Fields: -# - simple -# - relations (one2many, many2one, many2many) -# - function -# -# Fields Attributes: -# _classic_read: is a classic sql fields -# _type : field type -# readonly -# required -# size -# +""" Fields: + - simple + - relations (one2many, many2one, many2many) + - function + + Fields Attributes: + * _classic_read: is a classic sql fields + * _type : field type + * readonly + * required + * size +""" + import datetime as DT import string import sys @@ -51,6 +52,12 @@ def _symbol_set(symb): class _column(object): + """ Base of all fields, a database column + + An instance of this object is a *description* of a database column. It will + not hold any data, but only provide the methods to manipulate data of an + ORM record or even prepare/update the database to hold such a field of data. + """ _classic_read = True _classic_write = True _prefetch = True @@ -855,6 +862,15 @@ class function(_column): # --------------------------------------------------------- class related(function): + """Field that points to some data inside another field of the current record. + + Example:: + + _columns = { + 'foo_id': fields.many2one('my.foo', 'Foo'), + 'bar': fields.related('frol', 'foo_id', type='char', string='Frol of Foo'), + } + """ def _fnct_search(self, tobj, cr, uid, obj=None, name=None, domain=None, context=None): self._field_get2(cr, uid, obj, context) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 4141176fc5b..9578a4d356b 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -19,24 +19,25 @@ # ############################################################################## -# -# Object relationnal mapping to postgresql module -# . Hierarchical structure -# . Constraints consistency, validations -# . Object meta Data depends on its status -# . Optimised processing by complex query (multiple actions at once) -# . Default fields value -# . Permissions optimisation -# . Persistant object: DB postgresql -# . Datas conversions -# . Multi-level caching system -# . 2 different inheritancies -# . Fields: -# - classicals (varchar, integer, boolean, ...) -# - relations (one2many, many2one, many2many) -# - functions -# -# +""" + Object relational mapping to database (postgresql) module + * Hierarchical structure + * Constraints consistency, validations + * Object meta Data depends on its status + * Optimised processing by complex query (multiple actions at once) + * Default fields value + * Permissions optimisation + * Persistant object: DB postgresql + * Datas conversions + * Multi-level caching system + * 2 different inheritancies + * Fields: + - classicals (varchar, integer, boolean, ...) + - relations (one2many, many2one, many2many) + - functions + +""" + import calendar import copy import datetime @@ -123,8 +124,9 @@ class except_orm(Exception): class BrowseRecordError(Exception): pass -# Readonly python database object browser class browse_null(object): + """ Readonly python database object browser + """ def __init__(self): self.id = False @@ -152,6 +154,11 @@ class browse_null(object): # TODO: execute an object method on browse_record_list # class browse_record_list(list): + """ Collection of browse objects + + Such an instance will be returned when doing a ``browse([ids..])`` + and will be iterable, yielding browse() objects + """ def __init__(self, lst, context=None): if not context: @@ -161,13 +168,25 @@ class browse_record_list(list): class browse_record(object): + """ An object that behaves like a row of an object's table. + It has attributes after the columns of the corresponding object. + + Examples:: + + uobj = pool.get('res.users') + user_rec = uobj.browse(cr, uid, 104) + name = user_rec.name + """ logger = netsvc.Logger() def __init__(self, cr, uid, id, table, cache, context=None, list_class=None, fields_process=None): - ''' - table : the object (inherited from orm) - context : dictionary with an optional context - ''' + """ + @param cache a dictionary of model->field->data to be shared accross browse + objects, thus reducing the SQL read()s . It can speed up things a lot, + but also be disastrous if not discarded after write()/unlink() operations + @param table the object (inherited from orm) + @param context dictionary with an optional context + """ if fields_process is None: fields_process = {} if context is None: @@ -361,10 +380,10 @@ class browse_record(object): def get_pg_type(f): - ''' + """ returns a tuple (type returned by postgres when the column was created, type expression to create the column) - ''' + """ type_dict = { fields.boolean: 'bool', @@ -725,7 +744,7 @@ class orm_template(object): :param cr: database cursor :param user: current user id - :param select: id or list of ids + :param select: id or list of ids. :param context: context arguments, like lang, time zone :rtype: object or list of objects requested diff --git a/openerp/tools/misc.py b/openerp/tools/misc.py index 4167befd42d..a79bbb0cf49 100644 --- a/openerp/tools/misc.py +++ b/openerp/tools/misc.py @@ -124,16 +124,18 @@ def exec_command_pipe(name, *args): def file_open(name, mode="r", subdir='addons', pathinfo=False): """Open a file from the OpenERP root, using a subdir folder. + Example:: + >>> file_open('hr/report/timesheer.xsl') >>> file_open('addons/hr/report/timesheet.xsl') >>> file_open('../../base/report/rml_template.xsl', subdir='addons/hr/report', pathinfo=True) - @param name: name of the file - @param mode: file open mode - @param subdir: subdirectory - @param pathinfo: if True returns tupple (fileobject, filepath) + @param name name of the file + @param mode file open mode + @param subdir subdirectory + @param pathinfo if True returns tupple (fileobject, filepath) - @return: fileobject if pathinfo is False else (fileobject, filepath) + @return fileobject if pathinfo is False else (fileobject, filepath) """ import openerp.modules as addons adps = addons.module.ad_paths @@ -217,7 +219,7 @@ def flatten(list): """Flatten a list of elements into a uniqu list Author: Christophe Simonis (christophe@tinyerp.com) - Examples: + Examples:: >>> flatten(['a']) ['a'] >>> flatten('b') @@ -246,6 +248,8 @@ def flatten(list): def reverse_enumerate(l): """Like enumerate but in the other sens + + Usage:: >>> a = ['a', 'b', 'c'] >>> it = reverse_enumerate(a) >>> it.next() @@ -285,16 +289,14 @@ priorities = { } def html2plaintext(html, body_id=None, encoding='utf-8'): + """ From an HTML text, convert the HTML to plain text. + If @param body_id is provided then this is the tag where the + body (not necessarily ) starts. + """ ## (c) Fry-IT, www.fry-it.com, 2007 ## ## download here: http://www.peterbe.com/plog/html2plaintext - - """ from an HTML text, convert the HTML to plain text. - If @body_id is provided then this is the tag where the - body (not necessarily ) starts. - """ - html = ustr(html) from lxml.etree import tostring @@ -351,14 +353,16 @@ def html2plaintext(html, body_id=None, encoding='utf-8'): return html def generate_tracking_message_id(openobject_id): - """Returns a string that can be used in the Message-ID RFC822 header field so we - can track the replies related to a given object thanks to the "In-Reply-To" or - "References" fields that Mail User Agents will set. + """Returns a string that can be used in the Message-ID RFC822 header field + + Used to track the replies related to a given object thanks to the "In-Reply-To" + or "References" fields that Mail User Agents will set. """ return "<%s-openobject-%s@%s>" % (time.time(), openobject_id, socket.gethostname()) def _email_send(smtp_from, smtp_to_list, message, openobject_id=None, ssl=False, debug=False): - """Low-level method to send directly a Message through the configured smtp server. + """ Low-level method to send directly a Message through the configured smtp server. + :param smtp_from: RFC-822 envelope FROM (not displayed to recipient) :param smtp_to_list: RFC-822 envelope RCPT_TOs (not displayed to recipient) :param message: an email.message.Message to send @@ -427,17 +431,16 @@ def email_send(email_from, email_to, subject, body, email_cc=None, email_bcc=Non """Send an email. - Arguments: - - `email_from`: A string used to fill the `From` header, if falsy, + @param email_from A string used to fill the `From` header, if falsy, config['email_from'] is used instead. Also used for the `Reply-To` header if `reply_to` is not provided - `email_to`: a sequence of addresses to send the mail to. + @param email_to a sequence of addresses to send the mail to. """ if x_headers is None: x_headers = {} + if not (email_from or config['email_from']): raise ValueError("Sending an email requires either providing a sender " @@ -507,10 +510,9 @@ def sms_send(user, password, api_id, text, to): # FIXME: Use the logger if there is an error return True -#--------------------------------------------------------- -# Class that stores an updateable string (used in wizards) -#--------------------------------------------------------- class UpdateableStr(local): + """ Class that stores an updateable string (used in wizards) + """ def __init__(self, string=''): self.string = string @@ -526,7 +528,8 @@ class UpdateableStr(local): class UpdateableDict(local): - '''Stores an updateable dict to use in wizards''' + """Stores an updateable dict to use in wizards + """ def __init__(self, dict=None): if dict is None: @@ -624,8 +627,13 @@ class UpdateableDict(local): return self.dict.__ne__(y) -# Don't use ! Use res.currency.round() class currency(float): + """ Deprecate + + .. warning:: + + Don't use ! Use res.currency.round() + """ def __init__(self, value, accuracy=2, rounding=None): if rounding is None: @@ -1168,7 +1176,7 @@ def detect_ip_addr(): # times. def get_win32_timezone(): """Attempt to return the "standard name" of the current timezone on a win32 system. - @return: the standard name of the current win32 timezone, or False if it cannot be found. + @return the standard name of the current win32 timezone, or False if it cannot be found. """ res = False if (sys.platform == "win32"): @@ -1186,7 +1194,7 @@ def get_win32_timezone(): def detect_server_timezone(): """Attempt to detect the timezone to use on the server side. Defaults to UTC if no working timezone can be found. - @return: the timezone identifier as expected by pytz.timezone. + @return the timezone identifier as expected by pytz.timezone. """ try: import pytz @@ -1312,7 +1320,7 @@ def server_to_local_timestamp(src_tstamp_str, src_format, dst_format, dst_tz_nam @param ignore_unparsable_time: if True, return False if src_tstamp_str cannot be parsed using src_format or formatted using dst_format. - @return: local/client formatted timestamp, expressed in the local/client timezone if possible + @return local/client formatted timestamp, expressed in the local/client timezone if possible and if tz_offset is true, or src_tstamp_str if timezone offset could not be determined. """ if not src_tstamp_str: