# HG changeset patch # User Thierry Florac # Date 1518971682 -3600 # Node ID 6daed68877b3d711726b954c74fb225ec7f5b48b # Parent e7db8173ee0d5b90ecbc6ec51832cbc0eb74279d Updated doctests diff -r e7db8173ee0d -r 6daed68877b3 src/pyams_utils/doctests/README.txt --- a/src/pyams_utils/doctests/README.txt Sun Feb 18 17:34:17 2018 +0100 +++ b/src/pyams_utils/doctests/README.txt Sun Feb 18 17:34:42 2018 +0100 @@ -7,141 +7,4 @@ This package is composed of a set of utility functions, usable into any Pyramid application. - -Unicode functions ------------------ - -While working with extended characters sets containing accentuated characters, it's necessary to -convert strings to UTF8 so that they can be used without any conversion problem. - - >>> from pyams_utils import unicode - -'translate_string' is a utility function which can be used, for example, to generate an object's id -without space and with accentuated characters converted to their unaccentuated version: - - >>> sample = 'Mon titre accentué' - >>> unicode.translate_string(sample) - 'mon titre accentue' - -Results are lower-cased by default ; this can be avoided be setting the 'force_lower' argument -to False: - - >>> unicode.translate_string(sample, force_lower=False) - 'Mon titre accentue' - >>> unicode.translate_string(sample, force_lower=True, spaces='-') - 'mon-titre-accentue' - - >>> sample = 'Texte accentué avec "ponctuation" !' - >>> unicode.translate_string(sample, force_lower=True, spaces=' ') - 'texte accentue avec ponctuation' - >>> unicode.translate_string(sample, force_lower=True, remove_punctuation=False, spaces=' ') - 'texte accentue avec "ponctuation" !' - >>> unicode.translate_string(sample, force_lower=True, remove_punctuation=False, spaces='-') - 'texte-accentue-avec-"ponctuation"-!' - >>> unicode.translate_string(sample, force_lower=True, remove_punctuation=True, spaces='-') - 'texte-accentue-avec-ponctuation' - >>> unicode.translate_string(sample, force_lower=True, remove_punctuation=True, spaces=' ', keep_chars='!') - 'texte accentue avec ponctuation !' - - -If input string can contain 'slashes' (/) or 'backslashes' (\), they are normally removed ; -by using the 'escape_slashes' parameter, the input string is splitted and only the last element is -returned ; this is handy to handle filenames on Windows platform: - - >>> sample = 'Autre / chaîne / accentuée' - >>> unicode.translate_string(sample) - 'autre chaine accentuee' - >>> unicode.translate_string(sample, escape_slashes=True) - 'accentuee' - >>> sample = 'C:\\Program Files\\My Application\\test.txt' - >>> unicode.translate_string(sample) - 'cprogram filesmy applicationtest.txt' - >>> unicode.translate_string(sample, escape_slashes=True) - 'test.txt' - -To remove remaining spaces or convert them to another character, you can use the "spaces" parameter -which can contain any string to be used instead of initial spaces: - - >>> sample = 'C:\\Program Files\\My Application\\test.txt' - >>> unicode.translate_string(sample, spaces=' ') - 'cprogram filesmy applicationtest.txt' - >>> unicode.translate_string(sample, spaces='-') - 'cprogram-filesmy-applicationtest.txt' - -Spaces replacement is made in the last step, so using it with "escape_slashes" parameter only affects -the final result: - - >>> unicode.translate_string(sample, escape_slashes=True, spaces='-') - 'test.txt' - -Unicode module also provides encoding and decoding functions: - - >>> var = b'Cha\xeene accentu\xe9e' - >>> unicode.decode(var, 'latin1') - 'Chaîne accentuée' - >>> unicode.encode(unicode.decode(var, 'latin1'), 'latin1') == var - True - - >>> utf = 'Chaîne accentuée' - >>> unicode.encode(utf, 'latin1') - b'Cha\xeene accentu\xe9e' - >>> unicode.decode(unicode.encode(utf, 'latin1'), 'latin1') == utf - True - - -Dates functions ---------------- - -Dates functions are used to convert dates from/to string representation: - - >>> from datetime import datetime - >>> from pyams_utils import date - >>> now = datetime.fromtimestamp(1205000000) - >>> now - datetime.datetime(2008, 3, 8, 19, 13, 20) - -You can get an unicode representation of a date in ASCII format using 'unidate' fonction ; date is -converted to GMT: - - >>> udate = date.unidate(now) - >>> udate - '2008-03-08T19:13:20+00:00' - -'parse_date' can be used to convert ASCII format into datetime: - - >>> ddate = date.parse_date(udate) - >>> ddate - datetime.datetime(2008, 3, 8, 19, 13, 20, tzinfo=) - -'date_to_datetime' can be used to convert a 'date' type to a 'datetime' value ; if a 'datetime' value -is used as argument, it is returned 'as is': - - >>> ddate.date() - datetime.date(2008, 3, 8) - >>> date.date_to_datetime(ddate) - datetime.datetime(2008, 3, 8, 19, 13, 20, tzinfo=) - >>> date.date_to_datetime(ddate.date()) - datetime.datetime(2008, 3, 8, 0, 0) - - -Timezones handling ------------------- - -Timezones handling gave me headaches at first. I finally concluded that the best way (for me !) to handle -TZ data was to store every datetime value in GMT timezone. -As far as I know, there is no easy way to know the user's timezone from his request settings. So you can: -- store this timezone in user's profile, -- define a static server's timezone -- create and register a ServerTimezoneUtility to handle server default timezone. - -My current default user's timezone is set to 'Europe/Paris' ; you should probably update this setting in -'timezone.py' if you are located elsewhere. - - >>> from pyams_utils import timezone - >>> timezone.tztime(ddate) - datetime.datetime(2008, 3, 8, 19, 13, 20, tzinfo=) - -'gmtime' function can be used to convert a datetime to GMT: - - >>> timezone.gmtime(now) - datetime.datetime(2008, 3, 8, 19, 13, 20, tzinfo=) +Associated files provide additional automated doctests. \ No newline at end of file diff -r e7db8173ee0d -r 6daed68877b3 src/pyams_utils/doctests/dates.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_utils/doctests/dates.txt Sun Feb 18 17:34:42 2018 +0100 @@ -0,0 +1,57 @@ + +Dates functions +--------------- + +Dates functions are used to convert dates from/to string representation: + + >>> from datetime import datetime + >>> from pyams_utils import date + >>> now = datetime.fromtimestamp(1205000000) + >>> now + datetime.datetime(2008, 3, 8, 19, 13, 20) + +You can get an unicode representation of a date in ASCII format using 'unidate' fonction ; date is +converted to GMT: + + >>> udate = date.unidate(now) + >>> udate + '2008-03-08T19:13:20+00:00' + +'parse_date' can be used to convert ASCII format into datetime: + + >>> ddate = date.parse_date(udate) + >>> ddate + datetime.datetime(2008, 3, 8, 19, 13, 20, tzinfo=) + +'date_to_datetime' can be used to convert a 'date' type to a 'datetime' value ; if a 'datetime' value +is used as argument, it is returned 'as is': + + >>> ddate.date() + datetime.date(2008, 3, 8) + >>> date.date_to_datetime(ddate) + datetime.datetime(2008, 3, 8, 19, 13, 20, tzinfo=) + >>> date.date_to_datetime(ddate.date()) + datetime.datetime(2008, 3, 8, 0, 0) + + +Timezones handling +------------------ + +Timezones handling gave me headaches at first. I finally concluded that the best way (for me !) to handle +TZ data was to store every datetime value in GMT timezone. +As far as I know, there is no easy way to know the user's timezone from his request settings. So you can: +- store this timezone in user's profile, +- define a static server's timezone +- create and register a ServerTimezoneUtility to handle server default timezone. + +My current default user's timezone is set to 'Europe/Paris' ; you should probably update this setting in +'timezone.py' if you are located elsewhere. + + >>> from pyams_utils import timezone + >>> timezone.tztime(ddate) + datetime.datetime(2008, 3, 8, 19, 13, 20, tzinfo=) + +'gmtime' function can be used to convert a datetime to GMT: + + >>> timezone.gmtime(now) + datetime.datetime(2008, 3, 8, 19, 13, 20, tzinfo=) diff -r e7db8173ee0d -r 6daed68877b3 src/pyams_utils/doctests/request.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_utils/doctests/request.txt Sun Feb 18 17:34:42 2018 +0100 @@ -0,0 +1,68 @@ + +Managing requests +----------------- + +PyAMS_utils package provides some useful functions to handle requests. + +The 'check_request' function can be sure when you have to be sure that a request is active in +the current execution thread; if no "real" request is active, a new one is created: + + >>> from pyams_utils.request import query_request, check_request + >>> request = query_request() + >>> request is None + True + >>> request = check_request() + >>> request + + +If a new request is created "from scratch", it's registry is assigned to global registry: + + >>> request.registry + + +A request context can be used to activate a request into execution thread: + + >>> from pyramid.threadlocal import RequestContext + >>> with RequestContext(request) as context_request: + ... context_request is request + True + >>> with RequestContext(request): + ... context_request = check_request() + ... context_request is request + True + +Requests can now support annotations to set and retrieve any information to a given request: + + >>> from zope.annotation.interfaces import IAttributeAnnotatable, IAnnotations + >>> from zope.annotation.attribute import AttributeAnnotations + >>> from pyams_utils.registry import get_global_registry + >>> registry = get_global_registry() + >>> registry.registerAdapter(AttributeAnnotations, (IAttributeAnnotatable, ), IAnnotations) + + >>> from pyams_utils.request import get_request_data, set_request_data + >>> set_request_data(request, 'test', 'This is request data') + >>> get_request_data(request, 'test') + 'This is request data' + +Annotations can be used to automatically reify a given property into request annotations: + + >>> from pyams_utils.request import request_property + >>> class RequestPropertyTestClass(object): + ... + ... @request_property(key='My property') + ... def my_property(self): + ... print("This is my property") + ... return 1 + ... + >>> with RequestContext(request): + ... instance = RequestPropertyTestClass() + ... instance.my_property() + This is my property + 1 + +As property value is cached into request annotations, other property calls will just return +cached value: + + >>> with RequestContext(request): + ... instance.my_property() + 1 diff -r e7db8173ee0d -r 6daed68877b3 src/pyams_utils/doctests/unicode.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_utils/doctests/unicode.txt Sun Feb 18 17:34:42 2018 +0100 @@ -0,0 +1,80 @@ + +Unicode functions +----------------- + +While working with extended characters sets containing accentuated characters, it's necessary to +convert strings to UTF8 so that they can be used without any conversion problem. + + >>> from pyams_utils import unicode + +'translate_string' is a utility function which can be used, for example, to generate an object's id +without space and with accentuated characters converted to their unaccentuated version: + + >>> sample = 'Mon titre accentué' + >>> unicode.translate_string(sample) + 'mon titre accentue' + +Results are lower-cased by default ; this can be avoided by setting the 'force_lower' argument +to False: + + >>> unicode.translate_string(sample, force_lower=False) + 'Mon titre accentue' + >>> unicode.translate_string(sample, force_lower=True, spaces='-') + 'mon-titre-accentue' + + >>> sample = 'Texte accentué avec "ponctuation" !' + >>> unicode.translate_string(sample, force_lower=True, spaces=' ') + 'texte accentue avec ponctuation' + >>> unicode.translate_string(sample, force_lower=True, remove_punctuation=False, spaces=' ') + 'texte accentue avec "ponctuation" !' + >>> unicode.translate_string(sample, force_lower=True, remove_punctuation=False, spaces='-') + 'texte-accentue-avec-"ponctuation"-!' + >>> unicode.translate_string(sample, force_lower=True, remove_punctuation=True, spaces='-') + 'texte-accentue-avec-ponctuation' + >>> unicode.translate_string(sample, force_lower=True, remove_punctuation=True, spaces=' ', keep_chars='!') + 'texte accentue avec ponctuation !' + + +If input string can contain 'slashes' (/) or 'backslashes' (\), they are normally removed ; +by using the 'escape_slashes' parameter, the input string is splitted and only the last element is +returned ; this is handy to handle filenames on Windows platform: + + >>> sample = 'Autre / chaîne / accentuée' + >>> unicode.translate_string(sample) + 'autre chaine accentuee' + >>> unicode.translate_string(sample, escape_slashes=True) + 'accentuee' + >>> sample = 'C:\\Program Files\\My Application\\test.txt' + >>> unicode.translate_string(sample) + 'cprogram filesmy applicationtest.txt' + >>> unicode.translate_string(sample, escape_slashes=True) + 'test.txt' + +To remove remaining spaces or convert them to another character, you can use the "spaces" parameter +which can contain any string to be used instead of initial spaces: + + >>> sample = 'C:\\Program Files\\My Application\\test.txt' + >>> unicode.translate_string(sample, spaces=' ') + 'cprogram filesmy applicationtest.txt' + >>> unicode.translate_string(sample, spaces='-') + 'cprogram-filesmy-applicationtest.txt' + +Spaces replacement is made in the last step, so using it with "escape_slashes" parameter only affects +the final result: + + >>> unicode.translate_string(sample, escape_slashes=True, spaces='-') + 'test.txt' + +Unicode module also provides encoding and decoding functions: + + >>> var = b'Cha\xeene accentu\xe9e' + >>> unicode.decode(var, 'latin1') + 'Chaîne accentuée' + >>> unicode.encode(unicode.decode(var, 'latin1'), 'latin1') == var + True + + >>> utf = 'Chaîne accentuée' + >>> unicode.encode(utf, 'latin1') + b'Cha\xeene accentu\xe9e' + >>> unicode.decode(unicode.encode(utf, 'latin1'), 'latin1') == utf + True