base¶
This module defines base classes for python-textops3
activate_debug¶
textops.
activate_debug
()¶Activate debug logging on console
This function is useful when playing with python-textops3 through a python console. It is not recommended to use this function in a real application : use standard logging functions instead.
add_textop¶
textops.
add_textop
(class_or_func)¶Decorator to declare custom function or custom class as a new textops op
the custom function/class will receive the whole raw input text at once.
Examples
>>> @add_textop ... def repeat(text, n, *args,**kwargs): ... return text * n >>> 'hello' | repeat(3) 'hellohellohello'>>> @add_textop ... class cool(TextOp): ... @classmethod ... def op(cls, text, *args,**kwargs): ... return text + ' is cool.' >>> 'textops' | cool() 'textops is cool.'
add_textop_iter¶
textops.
add_textop_iter
(func)¶Decorator to declare custom ITER function as a new textops op
An ITER function is a function that will receive the input text as a LIST of lines. One have to iterate over this list and generate a result (it can be a list, a generator, a dict, a string, an int …)
Examples
>>> @add_textop_iter ... def odd(lines, *args,**kwargs): ... for i,line in enumerate(lines): ... if not i % 2: ... yield line >>> s = '''line 1 ... line 2 ... line 3''' >>> s >> odd() ['line 1', 'line 3'] >>> s | odd().tolist() ['line 1', 'line 3']>>> @add_textop_iter ... def sumsize(lines, *args,**kwargs): ... sum = 0 ... for line in lines: ... sum += int(re.search(r'\d+',line).group(0)) ... return sum >>> '''1492 file1 ... 1789 file2 ... 2015 file3''' | sumsize() 5296
dictmerge¶
textops.
dictmerge
(*dict_args)¶Merge as many dicts you want
Given any number of dicts, shallow copy and merge into a new dict, precedence goes to key value pairs in latter dicts.
Parameters: *dict_args (dict) – List of dicts Returns: a new merged dict Return type: dict Examples
>>> dictmerge({'a':1,'b':2},{'b':3,'c':4}) {'a': 1, 'b': 3, 'c': 4}
dformat¶
textops.
dformat
(format_str, dct, defvalue='-')¶Formats a dictionary, manages unkown keys
It works like
string.Formatter.vformat()
except that it accepts only a dict for values and a defvalue for not matching keys. Defvalue can be a callable that will receive the requested key as argument and return a string
Parameters:
- format_string (str) – Same format string as for
str.format()
- dct (dict) – the dict to format
- defvalue (str or callable) – the default value to display when the data is not in the dict
Examples
>>> d = {'count': '32591', 'soft': 'textops'} >>> dformat('{soft} : {count} dowloads',d) 'textops : 32591 dowloads' >>> dformat('{software} : {count} dowloads',d,'N/A') 'N/A : 32591 dowloads' >>> dformat('{software} : {count} dowloads',d,lambda k:'unknown_tag_%s' % k) 'unknown_tag_software : 32591 dowloads'
eformat¶
textops.
eformat
(format_str, lst, dct, defvalue='-')¶Formats a list and a dictionary, manages unkown keys
It works like
string.Formatter.vformat()
except that it accepts a defvalue for not matching keys. Defvalue can be a callable that will receive the requested key as argument and return a string
Parameters:
- format_string (str) – Same format string as for
str.format()
- lst (dict) – the list to format
- dct (dict) – the dict to format
- defvalue (str or callable) – the default value to display when the data is not in the dict
Examples
>>> d = {'count': '32591', 'soft': 'textops'} >>> l = ['Eric','Guido'] >>> eformat('{0} => {soft} : {count} dowloads',l,d) 'Eric => textops : 32591 dowloads' >>> eformat('{2} => {software} : {count} dowloads',l,d,'N/A') 'N/A => N/A : 32591 dowloads' >>> eformat('{2} => {software} : {count} dowloads',l,d,lambda k:'unknown_tag_%s' % k) 'unknown_tag_2 => unknown_tag_software : 32591 dowloads'
vformat¶
Same syntaxe asstring.Formatter.vformat()
DictExt¶
- class
textops.
DictExt
(*args, **kwargs)¶Extend dict class with new features
New features are :
- Access to textops operations with attribute notation
- All dict values (dict, list, str, bytes) are extended on-the-fly when accessed
- Access to dict values with attribute notation
- Add a key:value in the dict with attribute notation (one level at a time)
- Returns NoAttr object when a key is not in the Dict
- add modification on-the-fly
amend()
and rendering to stringrender()
Note
NoAttr
is a special object that returns alwaysNoAttr
when accessing to any attribute. it behaves likeFalse
for testing,[]
in foor-loops. The goal is to be able to use very long expression with dotted notation without being afraid to get an exception.Examples
>>> {'a':1,'b':2}.items().grep('a') Traceback (most recent call last): ... AttributeError: 'dict_items' object has no attribute 'grep'>>> DictExt({'a':1,'b':2}).items().grep('a') [('a', 1)]>>> d = DictExt({ 'this' : { 'is' : { 'a' : {'very deep' : { 'dict' : 'yes it is'}}}}}) >>> print(d.this['is'].a['very deep'].dict) yes it is >>> d.not_a_valid_key NoAttr >>> d['not_a_valid_key'] NoAttr >>> d.not_a_valid_key.and_i.can.put.things.after.without.exception NoAttr >>> for obj in d.not_a_valid_key.objects: ... do_things(obj) ... else: ... print('no object') no object>>> d = DictExt() >>> d.a = DictExt() >>> d.a.b = 'this is my logging data' >>> print(d) {'a': {'b': 'this is my logging data'}}>>> d = { 'mykey' : 'myval' } >>> d['mykey'] 'myval' >>> type(d['mykey']) <class 'str'> >>> d = DictExt(d) >>> d['mykey'] 'myval' >>> type(d['mykey']) <class 'textops.base.StrExt'>>>> d=DictExt() >>> d[0]=[] >>> d {0: []} >>> d[0].append(3) >>> d {0: [3]} >>> type(d[0]) <class 'textops.base.ListExt'>
amend
(*args, **kwargs)¶Modify on-the-fly a dictionary
The method will generate a new extended dictionary and update it with given params
Examples
>>> s = '''soft:textops ... count:32591''' >>> s | parse_indented() {'soft': 'textops', 'count': '32591'} >>> s | parse_indented().amend(date='2015-11-19') {'soft': 'textops', 'count': '32591', 'date': '2015-11-19'}
as_list
¶Convert to ListExt object
render
(format_string, defvalue='-')¶Render a DictExt as a string
It uses the fonction
dformat()
to format the dictionary
Parameters:
- format_string (str) – Same format string as for
str.format()
- defvalue (str or callable) – the default value to display when the data is not in the dict
Examples
>>> d = DictExt({'count': '32591', 'date': '2015-11-19', 'soft': 'textops'}) >>> d.render('On {date}, "{soft}" has been downloaded {count} times') 'On 2015-11-19, "textops" has been downloaded 32591 times' >>> d.render('On {date}, "{not_in_dict}" has been downloaded {count} times','?') 'On 2015-11-19, "?" has been downloaded 32591 times'
ListExt¶
- class
textops.
ListExt
¶Extend list class to gain access to textops as attributes
In addition, all list items (dict, list, str, bytes) are extended on-the-fly when accessed
Examples
>>> ['normal','list'].grep('t') Traceback (most recent call last): ... AttributeError: 'list' object has no attribute 'grep'>>> ListExt(['extended','list']).grep('t') ['extended', 'list']
as_list
¶Convert to ListExt object
StrExt¶
TextOp¶
- class
textops.
TextOp
(*args, **kwargs)¶Base class for text operations
All operations must be derived from this class. Subclasses must redefine an
op()
method that will be called when the operations will be triggered by an input text.
f
¶Execute operations, returns a float.
Examples
>>> echo('1789').f 1789.0 >>> echo('3.14').f 3.14 >>> echo('Tea for 2').f 0.0
g
¶Execute operations, return a generator when possible or a list otherwise
This is to be used ONLY when the input text has be set as the first argument of the first operation.
Examples
>>> echo('hello') echo('hello') >>> echo('hello').g ['hello'] >>> def mygen(): yield 'hello' >>> cut(mygen(),'l') # doctest: +ELLIPSIS cut(<generator object mygen at ...>,'l') >>> cut(mygen(),'l').g # doctest: +ELLIPSIS <generator object extend_type_gen at ...> >>> def mygen(): yield None >>> type(echo(None).g) # doctest: +ELLIPSIS <class 'NoneType'>
ge
¶Execute operations, return a generator when possible or a list otherwise, ( [] if the result is None ).
This works like
g
except it returns an empty list if the execution result is None.Examples
>>> echo(None).ge # doctest: +ELLIPSIS []
i
¶Execute operations, returns an int.
Examples
>>> echo('1789').i 1789 >>> echo('3.14').i 3 >>> echo('Tea for 2').i 0
j
¶Execute operations, return a string (join = ‘’)
This works like
s
except that joins will be done with an empty stringExamples
>>> echo(['hello','world']).j 'helloworld' >>> type(echo(None).j) <class 'NoneType'>
je
¶Execute operations, returns a string ( ‘’ if the result is None, join=’’).
This works like
j
except it returns an empty string if the execution result is None.Examples
>>> echo(None).je ''
l
¶Execute operations, return a list
This is to be used ONLY when the input text has be set as the first argument of the first operation.
Examples
>>> echo('hello') echo('hello') >>> echo('hello').l ['hello'] >>> type(echo(None).g) <class 'NoneType'>
le
¶Execute operations, returns a list ( [] if the result is None ).
This works like
l
except it returns an empty list if the execution result is None.Examples
>>> echo(None).le []
n
¶Execute operations, do not convert, do not return anything
If _process() returns a generator, it is consumed
Examples
>>> echo('1789').length().n
- classmethod
op
(text, *args, **kwargs)¶This method must be overriden in derived classes
pp
¶Execute operations, return Prettyprint version of the result
Examples:
>>> s = ''' ... a:val1 ... b: ... c:val3 ... d: ... e ... : val5 ... f ... :val6 ... g:val7 ... f: val8''' >>> print(parse_indented(s).r) {'a': 'val1', 'b': {'c': 'val3', 'd': {'e': 'val5', 'f': 'val6'}, 'g': 'val7'}, 'f': 'val8'} >>> print(parse_indented(s).pp) { 'a': 'val1', 'b': {'c': 'val3', 'd': {'e': 'val5', 'f': 'val6'}, 'g': 'val7'}, 'f': 'val8'}
r
¶Execute operations, do not convert.
Examples
>>> echo('1789').length().l [4] >>> echo('1789').length().s '4' >>> echo('1789').length().r 4
s
¶Execute operations, return a string (join = newline)
This is to be used ONLY when the input text has be set as the first argument of the first operation. If the result is a list or a generator, it is converted into a string by joinning items with a newline.
Examples
>>> echo('hello') echo('hello') >>> echo('hello').s 'hello' >>> echo(['hello','world']).s 'hello\nworld' >>> type(echo(None).s) <class 'NoneType'>
BytesExt¶
- class
textops.
BytesExt
¶Extend bytes class to gain access to textops as attributes
Examples
>>> b'normal bytes'.cut() Traceback (most recent call last): ... AttributeError: 'bytes' object has no attribute 'cut'>>> BytesExt(b'extended bytes').cut() [b'extended', b'bytes']
as_list
¶Convert to ListExt object