Exemplo n.º 1
0
def _main(cmd):
    import sys
    dirs = cmd.argv or (".", )
    if cmd.newlines:
        sep = "\n"
    else:
        sep = cmd.separator
    if cmd.transitive:
        fct = subdirs_transitive
    elif cmd.basenames:
        fct = subdir_names
    else:
        fct = subdirs
    result = []
    for d in dirs:
        result.extend(fct(d))
    for exc in cmd.exclude:
        result = [r for r in result if r != exc]
    if cmd.re_exclude:
        from _TFL.Regexp import Regexp
        exc = Regexp(cmd.re_exclude)
        result = [r for r in result if not exc.search(r)]
    if cmd.lstrip:
        result = [r.lstrip(cmd.lstrip) for r in result]
    if result:
        result.sort()
        sys.stdout.write(sep.join(result) + "\n")
Exemplo n.º 2
0
def _main (cmd) :
    import sys
    dirs = cmd.argv or (".", )
    if cmd.newlines :
        sep = "\n"
    else :
        sep = cmd.separator
    if cmd.transitive :
        fct = subdirs_transitive
    elif cmd.basenames :
        fct = subdir_names
    else :
        fct = subdirs
    result = []
    for d in dirs :
        result.extend (fct (d))
    for exc in cmd.exclude :
        result = [r for r in result if r != exc]
    if cmd.re_exclude :
        from _TFL.Regexp import Regexp
        exc    = Regexp (cmd.re_exclude)
        result = [r for r in result if not exc.search (r)]
    if cmd.lstrip :
        result = [r.lstrip (cmd.lstrip) for r in result]
    if result :
        result.sort ()
        sys.stdout.write (sep.join (result) + "\n")
Exemplo n.º 3
0
 def _m_default_ui_name(cls, base_name):
     result = base_name
     Roles = getattr(cls, "Roles", [])
     if Roles and all(R.E_Type for R in Roles):
         rn_pat = Regexp \
             ( "^"
             + "_(.+)_".join (R.E_Type.type_base_name for R in Roles)
             + "$"
             )
         if rn_pat.match(base_name):
             cs = rn_pat.groups()
             ns = tuple(R.E_Type.ui_name for R in Roles)
             result = filtered_join \
                 (" ", itertools.chain (* paired (ns, cs)))
     return result
Exemplo n.º 4
0
 def _m_default_ui_name (cls, base_name) :
     result = base_name
     Roles  = getattr (cls, "Roles", [])
     if Roles and all (R.E_Type for R in Roles) :
         rn_pat = Regexp \
             ( "^"
             + "_(.+)_".join (R.E_Type.type_base_name for R in Roles)
             + "$"
             )
         if rn_pat.match (base_name) :
             cs     = rn_pat.groups ()
             ns     = tuple (R.E_Type.ui_name for R in Roles)
             result = filtered_join \
                 (" ", itertools.chain (* paired (ns, cs)))
     return result
Exemplo n.º 5
0
 def _trailing_unit_pat(self):
     pat = "(?P<unit>%s)\s*$" % \
         ( "|".join
             (   re.escape (u)
             for u in sorted (self.Kind.u_map, key = lambda x : (len (x), x))
             )
         ,
         )
     return Regexp(pat)
Exemplo n.º 6
0
 def _gen():
     for p in patterns:
         if p == "*":
             yield self._rules
         elif p.startswith(":"):
             for scope in (CAL.Day_Rule, CAL):
                 cls = getattr(scope, p[1:], None)
                 if cls is not None:
                     break
             else:
                 raise NameError(p)
             yield (r for r in self._rules if isinstance(r, cls))
         elif p.startswith("~"):
             from _TFL.Regexp import Regexp
             re = Regexp(p[1:])
             yield (r for r in self._rules if re.search(r.name))
         else:
             rbn = self.rules_by_name
             yield \
                 ( rbn [n]
                 for n in self.rule_name_trie.completions (p) [0]
                 )
Exemplo n.º 7
0
 def __new__ (cls, cc, country, pat, ** kw) :
     cc    = cc.upper ()
     pat   = Regexp   ("^" + pat + "$")
     Table = cls.Table
     if cc in Table :
         ex = Table [cc]
         raise ValueError \
             ( "Rule for %s is already defined as %s; got %s"
             % (cc, ex.pat._pattern.pattern, pat._pattern.pattern)
             )
     result = Table [cc] = cls.__c_super.__new__ \
         (cls, cc, country, pat, ** kw)
     result._init_ (cc, country, pat, ** kw)
     return result
Exemplo n.º 8
0
class Country_0(Country):
    """Country without further information about ndc and sn."""

    regexp = Multi_Regexp \
        ( Regexp
            ( r" *0? *"
              r"[-/]?"
              r"(?P<ndc>\d{1,4})"
              r"(?:[- /](?P<sn>[- 0-9]+)?)?$"
            )
        , Regexp
            ( r" *0? *"
              r"\("
              r"(?P<ndc>\d{1,4})"
              r"\) *"
              r"(?P<sn>[- 0-9]+)?$"
            )
        )

    def _split_error_tail(self, tail):
        return \
            ( "".join
                ( ( self.__super._split_error_tail (tail)
                  , "\n    "
                  , _T
                      ( "Network destination code "
                        "and subscriber number need to be separated "
                        "by a space or dash."
                      )
                  )
                )
            )

    # end def _split_error_tail

    def __bool__(self):
        return False
Exemplo n.º 9
0
class A_DNS_Label(Syntax_Re_Mixin, A_String):
    """ A single DNS label (without dots)
        See rfc1034 *and* rfc1123 section 2.1 for details.
    """

    max_length = 63
    ignore_case = True
    syntax          = _ \
        ( u"A label starts"
           " with a letter or digit and is optionally followed by letters,"
           " digits or dashes and ends with a letter or digit. "
           "A label may be up to 63 characters long."
        )
    _label = r"[a-zA-Z0-9](?:[-a-zA-Z0-9]{0,61}[a-zA-Z0-9])?"
    _syntax_re = Regexp(_label)
Exemplo n.º 10
0
def _main (cao) :
    cao_path       = list (cao.path or [])
    summary        = new_summary ()
    py_executables = [sys.executable] + list (cao.Extra_Interpreters)
    py_options     = sos.python_options ()
    py_vs          = "[Python %s]" % ", ".join \
        (sorted (py_version (pyx) for pyx in py_executables))
    if cao.RExclude :
        x_pat      = Regexp (cao.RExclude)
        exclude    = x_pat.search
    elif cao.exclude :
        exclude    = lambda a : fnmatch (a, cao.exclude)
    else :
        exclude    = lambda a : False
    run_dir = run_app_tests_dir_transitive \
        if cao.transitive else run_app_tests_dir
    start = _timer ()
    for a in cao.argv :
        runner = run_dir if sos.path.isdir (a) else run_app_tests_mod
        runner (a, exclude, py_executables, py_options, summary)
    if cao.summary :
        et = " in %7.5fs" % (_timer () - start, )
        if summary.failed :
            fmt = "%(argv)s fails %(f)s of %(t)s app-tests in %(cases)s test-cases%(et)s %(py_vs)s"
        else :
            fmt = "%(argv)s passes all of %(t)s app-tests in %(cases)s test-cases%(et)s %(py_vs)s"
        print ("=" * 79, file = sys.stderr)
        print \
            ( fmt % TFL.Caller.Scope
                ( argv   = " ".join (cao.argv)
                , cases  = summary.cases
                , et     = et
                , f      = summary.failed
                , t      = summary.total
                )
            , file = sys.stderr
            )
        print \
            ( "    %s"
            % ("\n    ".join ("%-68s : %s" % f for f in summary.failures))
            , file = sys.stderr
            )
        if summary.excluded :
            print \
                ("    %s excluded" % (", ".join (summary.excluded), )
                , file = sys.stderr
                )
Exemplo n.º 11
0
Arquivo: UCD.py Projeto: JPilarr/tapyr
    def create_map \
            ( self
            , ignore_categories = {"Cc", "Cs", "Co", "Cn", "Zl"}
            , ignore_prefixes   = _ignore_prefixes
            ) :
        """Create a map char-id -> char-code.

        `char-id` is a valid Python identifier derived from `unidoce.name`.
        """
        from _TFL.Ascii          import sanitized_filename
        from _TFL.formatted_repr import formatted_repr
        from _TFL.Regexp         import Regexp, re
        import unicodedata
        ignore_categories = Regexp ("|".join (sorted (ignore_categories)))
        ignore_prefixes   = Regexp ("|".join (sorted (ignore_prefixes)))
        result            = {}
        for i in range (0x1, 0xf000) :
            c   = chr (i)
            cat = unicodedata.category (c)
            if ignore_categories.match (cat) :
                continue
            try :
                ucd_name    = unicodedata.name (c)
            except ValueError :
                continue
            id = sanitized_filename (ucd_name.lower ()).replace ("-", "_")
            if not ignore_prefixes.search (id) :
                result [id] = r"u%04x" % i
        result = "\n".join \
            ( ( "# -*- coding: utf-8 -*-"
              , "# Copyright (C) 2020 Mag. Christian Tanzer All rights reserved"
              , "# Generated automatically, do not change manually!"
              , ""
              , "id_to_chr_map = \\"
              , formatted_repr (result).replace (": 'u", r": '\u")
              )
            )
        return result
Exemplo n.º 12
0
from   _TFL.Regexp         import Regexp, re
from   _TFL.pyk            import pyk
from   _TFL                import sos
from   _TFL.subdirs        import subdirs_transitive

import _TFL.CAO

ignore_imports = set (("__builtin__", "__future__"))
import_pat     = Regexp \
    ( r"^\s* (?: from | import)\s+ "
      r"(?P<imported> [_A-Za-z0-9]+)"
      r"(?: \. (?P<modules> [_A-Za-z0-9.]+))?"
    , re.X | re.MULTILINE
    )
pns_pat        = Regexp (r"^_[A-Z]\w+$")

def external_imports (pkg_name, pkg_path, ignore_imports = ignore_imports) :
    """Return the set of external imports of package at `pkg_path`"""
    result = set ()
    for m in sos.listdir_ext (pkg_path, ".py") :
        result.update (external_module_imports (pkg_name, m, ignore_imports))
    for s in subdirs_transitive (pkg_path) :
        result.update (external_imports (pkg_name, s, ignore_imports))
    return result
# end def external_imports

def external_module_imports \
        (pkg_name, mod_path, ignore_imports = ignore_imports) :
    """Return the set of external imports of module at `mod_path`."""
    result = set ()
Exemplo n.º 13
0
 def cc_regexp_strict(cls):
     return Regexp(r"^ *(?:(?:\+ *|00)" + cls.cc_matcher_fragment + r")")
Exemplo n.º 14
0
class _Help_(TFL.Meta.Object):

    item_sep = "\n"

    usage_format = "Usage     :\n    %s"
    usage_format_option = "[option]..."
    usage_sep = " "

    arg_title = "Arguments :"
    arg_head_format = "    %-*s"
    arg_desc_format = "        %s"
    arg_desc_leader = "\n        "
    arg_sep = "\n"

    opt_title = "Options   :"
    opt_head_format = "    -%-*s : %s = %s"
    opt_head_format_B = "    -%-*s"
    opt_desc_format = "        %s"
    opt_desc_leader = "\n        "
    opt_sep = "\n"

    nl_pat = Regexp("\n\\s*")

    def __init__(self, cmd):
        self.cmd = cmd
        self.usage = self._usage(cmd)
        self.description = self._description(cmd)
        self.args = self._args(cmd)
        self.opts = self._opts(cmd)

    # end def __init__

    def __str__(self):
        result = [self.usage]
        for t in (self.description, self.args, self.opts):
            if t:
                result.append(t)
        return self.item_sep.join(result)

    # end def __str__

    def _formatted(self, format, *args):
        return format % args

    # end def _formatted

    def _cmd_name(self, cmd):
        return cmd.script_name

    # end def _cmd_name

    def _usage(self, cmd):
        result = [self._formatted(self.usage_format, self._cmd_name(cmd))]
        if cmd.option:
            result.append(self.usage_format_option)
        if cmd.argument:
            for i, a in enumerate(cmd.argument):
                result.append(self._fmt_arg_usage(cmd, a.name, i))
            self._add_rest_args(cmd, result)
        elif cmd._min_args > 0 or cmd._max_args > 0:
            self._add_rest_args(cmd, result)
        return self.usage_sep.join(result)

    # end def _usage

    def _description(self, cmd):
        if cmd._description:
            leader = "\n    "
            result = self._formatted \
                ( "%s%s", leader, self.nl_pat.sub (leader, cmd._description))
        else:
            result = ""
        return result

    # end def _description

    def _max_length(self, names):
        return max(names)

    # end def _max_length

    def _args(self, cmd):
        result = []
        args = [a for a in cmd.argument if a.description or a.explanation]
        if args:
            result.append(self.arg_title)
            leader = self.arg_desc_leader
            alen = self._max_length([len(a.name) for a in args])
            for a in sorted(args):
                result.append \
                    (self._formatted (self.arg_head_format, alen, a.name))
                for t in (a.description, a.explanation):
                    if t:
                        result.append \
                            ( self._formatted
                                  ( self.arg_desc_format
                                  , self.nl_pat.sub (leader, t)
                                  )
                            )
        return self.arg_sep.join(result)

    # end def _args

    def _opts(self, cmd):
        result = []
        opts   = \
             [ (n, o) for (n, o) in pyk.iteritems (cmd.option)
                      if n == o.name and not o.hide
             ]
        if opts:
            result.append(self.opt_title)
            leader = self.opt_desc_leader
            olen = self._max_length([len(o.name) for (n, o) in opts])
            for n, o in sorted(opts):
                if o.type == "B":
                    result.append \
                        (self._formatted (self.opt_head_format_B, olen, n))
                else:
                    result.append \
                        ( self._formatted
                              ( self.opt_head_format
                              , olen, n
                              , cmd.type_specifiers.get (o.type, "<string>")
                              , o.default or "<None>"
                              )
                        )
                for t in (o.description, o.explanation):
                    if t:
                        result.append \
                            ( self._formatted
                                  ( self.opt_desc_format
                                  , self.nl_pat.sub (leader, t)
                                  )
                            )
        return self.opt_sep.join(result)

    # end def _opts

    def _fmt_arg_usage(self, cmd, name, i, header=""):
        if i < cmd._min_args:
            return name
        else:
            return "%s[%s]" % (header, name)

    # end def _fmt_arg_usage

    def _fmt_arg(self, cmd, name, i, header=""):
        if i < cmd._min_args:
            return name
        else:
            return "%s[%s]" % (header, name)

    # end def _fmt_arg

    def _add_rest_args(self, cmd, result):
        max_args = cmd._max_args
        for i in range(len(cmd.argument), min(8, max_args)):
            result.append(self._fmt_arg(cmd, "arg-%d" % (i + 1), i))
        if max_args > 8:
            result.append \
                ( self._fmt_arg
                      (cmd, "arg-%d" % (max_args), max_args - 1, "...")
                )
        elif max_args == -1:
            result[-1] = result[-1] + "..."
Exemplo n.º 15
0
class Arg(TFL.Meta.Object):

    kind = "argument"
    paren_pat = Regexp("""^(.*)$""")
    range_pat    = Regexp \
        ( r"""^\s*"""
          r"""(?P<head> (?: 0[xX])? \d+)"""
          r"""\s*"""
          r"""\.\."""
          r"""\s*"""
          r"""(?P<tail> (?: 0[xX])? \d+)"""
          r"""\s*"""
          r"""(?: : (?P<delta> \d+))?"""
          r"""\s*$"""
        , re.X
        )
    cooks        = dict \
        ( B      = bool
        , F      = _cook_F
        , I      = int
        , L      = TFL.r_eval
        , P      = TFL.sos.expanded_path
        , S      = identity
        , T      = identity
        , U      = long
        , X      = _cook_X
        )

    def __init__(self,
                 name="",
                 type="",
                 default="",
                 description="",
                 explanation="",
                 cook=None):
        self.name = name
        self.type = (type or "S")[0].upper()
        self.default = self.cooked_default = default
        self.description = description
        self.explanation = explanation
        self.value = None
        self.pos = 0
        self.cook = cook or self.cooks[self.type]
        self._cook_default(default)

    # end def __init__

    def _cook_default(self, default):
        self.value = self._cooked_value(default)

    # end def _cook_default

    def set_value(self, value, pos):
        self.raw_value = value
        self._set_value(value, pos)

    # end def set_value

    def _set_value(self, value, pos):
        self.value = self._cooked_value(value)
        self.pos = pos

    # end def _set_value

    def _cooked_value(self, value):
        if value in ("", None):
            value = self.cooked_default
        if isinstance(value, pyk.string_types):
            try:
                cook = self.cook
                if self.type in "L" and not self.paren_pat.match(value):
                    value = "(%s)" % (value, )
                try:
                    value = cook(value)
                except ValueError:
                    ### `eval' handles expressions
                    value = cook(TFL.r_eval(value))
            except Exception as exc:
                print(exc)
                raise Cmd_Error \
                    ( "Invalid value `%s' for %s `%s' of type `%s'"
                    % (value, self.kind, self.name, self.type)
                    )
        return value

    # end def _cooked_value

    def __eq__(self, rhs):
        if hasattr(rhs, "name"):
            rhs = rhs.name
        return self.name == rhs

    # end def __eq__

    def __hash__(self):
        return hash(self.name)

    # end def __hash__

    def __lt__(self, rhs):
        if hasattr(rhs, "name"):
            rhs = rhs.name
        return self.name < rhs

    # end def __lt__

    def __repr__(self):
        return "%s (%s, %s, %s, %s, %d)" % \
            ( self.__class__.__name__
            , self.name, self.type, self.cooked_default, self.value, self.pos
            )
Exemplo n.º 16
0
from   _TFL.Package_Namespace import \
     Derived_Package_Namespace, Package_Namespace
from _TFL.pyk import pyk
from _TFL.Regexp import Regexp, re

import _MOM.Entity
import _MOM.Link
import _MOM.Object

import _TFL._Meta.M_Class
import _TFL._Meta.Object
import _TFL._Meta.Once_Property
import _TFL.Caller

_doc_pat = Regexp(r"\s+ of \s+ ([A-Za-z0-9_.]+)$", re.VERBOSE)


class _Lazy_Resolver_(TFL.Meta.Object):
    """Lazy resolver for PNS-specific base classes derived from their
       corresponding base classes in the parent PNS (default: MOM).
    """

    _MOM_bases = None
    _MOM_base_parents = None

    def __init__(self, PNS, parent_PNS, module_name):
        self.PNS = PNS
        self.parent_PNS = parent_PNS
        self.module_name = module_name
        ### trigger computation of `MOM_bases` here to limit to real MOM base
Exemplo n.º 17
0
#    Quote TeX-critical characters
#
# Revision Dates
#    29-Jan-2004 (CT)  Creation
#    11-May-2004 (RMA) Added tex_quoted_no_underscore and
#                      tex_quoted_underscore_word_with_path
#    01-Jun-2004 (RMA) Added {} to word boundaries to fix
#                      tex_quoted_underscore_word_with_path
#    ««revision-date»»
#--

from _TFL import TFL
from _TFL.pyk import pyk
from _TFL.Regexp import Regexp, re

_tex_pi_symbols = Regexp(r"[«»]", re.X)
_tex_to_quote = Regexp(r"([\\#~%&${}^])", re.X)
_tex_underscore = Regexp(r"([_])", re.X)
_tex_tt_symbols = Regexp(r"[<>+*|]", re.X)
_tex_diacritics = Regexp(r"[äöüÄÖÜß«»]")

_word_boundaries = "[^ ()}{,\t\n\r\f\v]"

_tex_path_text  = Regexp \
    (r"(%s*?[_]%s*)"  % (_word_boundaries, _word_boundaries), re.X)


def _tex_subs_pi_symbols(match):
    m = match.group(0)
    i = {"«": 225, "»": 241}[m]
    return r"\Pisymbol{psy}{%d}" % (i, )
Exemplo n.º 18
0
 def __init__ (self, tag) :
     pattern_pat   = self.pattern_pat
     self.head_tag = Regexp (pattern_pat % (tag, "START"), re.X)
     self.else_tag = Regexp (pattern_pat % (tag, "ELSE"),  re.X)
     self.tail_tag = Regexp (pattern_pat % (tag, "END"),   re.X)
     self.line_tag = Regexp (pattern_pat % (tag, "LINE"),  re.X)
Exemplo n.º 19
0
class App_Type_Wrapper(TFL.Meta.Object):
    """SAW specific information about a derived App_Type"""

    db_sig = (2, )
    """Change `db_sig` when a code change in SAW makes db incompatible"""

    no_identifier_pat = Regexp(r"\W")

    def __init__(self, app_type):
        self.app_type = app_type
        self.DBW = DBW = app_type.DBW
        self.PNS = PNS = DBW.PNS
        self.e_types_t = []
        self.et_map = {}
        self.tn_map = {}
        self.metadata = SA.schema.MetaData()
        self.SA_Type = PNS.SA_Type(self)
        self.sequences = []
        self.seq_map = {}
        self.spk_names = set()

    # end def __init__

    def add(self, etw):
        tn = etw.type_name
        if etw.sa_table is not None:
            self.e_types_t.append(etw)
            seq = etw.sequence
            if seq:
                self.sequences.append(seq)
                name = seq.attr.name
                seq_map = self.seq_map
                seq_map[tn] = seq
                if name in ("cid", "pid"):
                    assert not name in seq_map
                    seq_map[name] = seq
        self.et_map[tn] = etw
        spk_name = etw.spk_name
        if spk_name:
            self.spk_names.add(spk_name)

    # end def add

    def finalize(self):
        tn_map = self.tn_map
        names  = ichain \
            ( [""]
            , sorted
                ( k for k, etw in pyk.iteritems (self.et_map)
                    if  etw.e_type.has_identity
                )
            )
        for tid, tn in enumerate(names):
            tn_map.update(((tid, tn), (tn, tid)))

    # end def finalize

    def reset_cache(self):
        for etw in pyk.itervalues(self.et_map):
            etw.reset_cache()

    # end def reset_cache

    def __getitem__(self, key):
        key = getattr(key, "type_name", key)
        return self.et_map[key]
Exemplo n.º 20
0
license_preamble_pat = Regexp \
    ( r"This +\w+ +is +part +of +the +\w+ +(?P<pkg>(?:\w+\.)+) *$"
    , re.MULTILINE
    )

module_kind_pat = Regexp \
    ( r"(?P<head>This +)(?P<kind>\w+)(?P<tail> +is +)"
    , re.MULTILINE
    )

old_license_head_pats = \
    ( Regexp
        ( r"^(?P<lead> *(?:\#+|\*+|//|;+) +)"
          r"This \w+ is free software[;:] you can redistribute it and/or"
          r".*"
          r"Foundation, Inc., 675 Mass Ave, Cambridge, MA q?02139, USA."
        , re.DOTALL | re.MULTILINE
        )
    , Regexp
        ( r"^(?P<lead> *(?:\#+|\*+|//|;+) +)"
          r"This \w+ is free software[;:] you can redistribute it and/or"
          r".*"
          r"51 Franklin St, Fifth Floor, Boston, MA +02110-1301 +USA"
        , re.DOTALL | re.MULTILINE
        )
    , Regexp
        ( r"^(?P<lead> *(?:\#+|\*+|//|;+) +)"
          r"This \w+ is free software[;:] you can redistribute it and/or"
          r".*"
          r"along with this \w+[.;] *[Ii]f not, see <http://www.gnu.org/licenses/>."
Exemplo n.º 21
0
import _TFL.Decorator
import _TFL._Meta.Object

from   reportlab.pdfgen.canvas   import Canvas
from   reportlab.lib             import pagesizes, units
from   reportlab.pdfbase         import pdfmetrics
from   reportlab.pdfbase.ttfonts import TTFont

import subprocess
import sys
import reportlab.lib.pagesizes
import time

media   = {k : ps for k, ps in pagesizes.__dict__.items () if k.isupper ()}

_2equal_sign_pat    = Regexp ("={2,}")
_4equal_sign_pat    = Regexp ("={4,}")
_minus_sign_pat     = Regexp ("-{4,}")
_underscore_pat     = Regexp ("_{3,}")
_underline_pat      = Regexp ("(?:.\b_)+")

class Color (TFL.Meta.Object) :

    black       = 0.000, 0.000, 0.000
    gray_10     = 0.100, 0.100, 0.100
    gray_20     = 0.200, 0.200, 0.200
    gray_30     = 0.300, 0.300, 0.300
    gray_40     = 0.400, 0.400, 0.400
    gray_50     = 0.500, 0.500, 0.500
    gray_60     = 0.600, 0.600, 0.600
    gray_70     = 0.700, 0.700, 0.700
Exemplo n.º 22
0
class Plugin_Packager (TFL.Meta.Object) :

    _leading_underscore = Regexp ("^_")

    def __init__ \
        ( self, pi_root_name, ap_closure, import_path, target_root
        , ignore = None
        ) :
        assert "_Plugins" not in ap_closure.pym_dict
        self.pi_root_name  = pi_root_name
        self.ap_closure    = ap_closure
        self.import_path   = import_path
        self.target_root   = Dirname (target_root).name
        self.pi_closure    = TFL.Import_Closure \
            (pi_root_name, import_path, ignore)
        self.delta_closure = dc = self.pi_closure - ap_closure
        pi_packages        = \
            [ p for p in pyk.itervalues (dc.pkg_dict)
                if  p.pkg.startswith ("_Plugins") and p.level == 1
            ]
        assert len (pi_packages) == 1
        self.pi_package    = pip  = pi_packages [0]
        assert dc.root_pym.pkg   == pip.pkg, "%s:%s" % (dc.root_pym.pkg, pip.pkg)
        self.plugin_name          = self._get_name (pip)
        self._setup_target_packages (pip)
        self._copy_modules          ()
        self._make_setup_file       ()
    # end def __init__

    def _copy_modules (self) :
        for pym in self.py_modules + self.py_packages :
            code = self._read_source_file (pym)
            self._write_target_file       (pym, code)
    # end def _copy_modules

    def _get_name (self, pip) :
        try :
            sys_path = list (sys.path)
            sys.path [0:0] = self.import_path
            m = TFL.import_module ("%s.Version" % pip.pkg)
            return m.Version.productid
        finally :
            sys.path = sys_path
    # end def _get_name

    def _make_setup_file (self) :
        pname = self.plugin_name
        fname = TFL.sos.path.join (self.target_root, "_setup.py")
        sf    = open (fname, "w")
        sf.write     ("# Setup code for plugin %s\n\n" % pname)
        sf.write     ("from _TFL.Importers import Plugin_Importer\n\n")
        needs_sys_path = False
        for pyp in sorted (self.py_packages, key = TFL.Getter.pkg) :
            sf.write \
                ( "Plugin_Importer.register ('%s', '%s')\n"
                % (pname, pyp.pkg)
                )
            if len (pyp.pkg.split (".")) == 1 :
                needs_sys_path = True
        if needs_sys_path :
            sf.write \
                ( "Plugin_Importer.register_at_sys_path ('%s')\n"
                % (pname, )
                )
        for pym in sorted (self.py_modules, key = TFL.Getter.rel_name) :
            code = self._read_source_file (pym)
            m    = hashlib.md5 (code)
            sf.write \
              ( "Plugin_Importer.tag_module ('%s', '%s', '%s')\n"
              % (pname, pym.rel_name, m.hexdigest ())
              )
        sf.close     ()
    # end def _make_setup_file

    def _make_target_dir (self, pym) :
        pym_dir = TFL.sos.path.split (pym.target_path) [0]
        if not TFL.sos.path.isdir (pym_dir) :
            TFL.sos.mkdir_p (pym_dir)
    # end def _make_target_dir

    def _pns_from_pkg (self, pkg) :
        return ".".join \
            ([self._leading_underscore.sub ("", p) for p in pkg.split (".")])
    # end def _pns_from_pkg

    def _read_source_file (self, pym) :
        source = open        (pym.path_name)
        code   = source.read ()
        source.close         ()
        return code
    # end def _read_source_file

    def _setup_target_packages (self, pip) :
        dc      = self.delta_closure
        path    = TFL.sos.path
        sep     = TFL.sos.sep
        self.pym_dict    = pym_dict    = {}
        self.py_modules  = pyms        = []
        self.py_packages = pyps        = []
        for pym in dc.pym_dict.values () :
           for pyp in pym.pkg_chain () :
               if pyp.rel_name not in dc.pym_dict :
                   dc._add (pyp)
        for pym in pyk.itervalues (dc.pym_dict) :
            pym.target_pkg  = pym.pkg
            pym.target_path = path.join \
                (self.target_root, pym.pkg.replace (".", sep), pym.base_path)
            pym.source_pns = self._pns_from_pkg (pym.pkg)
            pym.target_pns = self._pns_from_pkg (pym.target_pkg)
            if pym.is_package :
                self._make_target_dir (pym)
                pym.source_mod = pym.pkg
                pym.target_mod = pym.target_pkg
                pyps.append (pym)
            else :
                pym.source_mod = ".".join ((pym.pkg,        pym.base_name))
                pym.target_mod = ".".join ((pym.target_pkg, pym.base_name))
                pyms.append (pym)
            pym_dict [pym.source_mod] = pym
    # end def _setup_target_packages

    def _write_target_file (self, pym, code) :
        target = open (pym.target_path, "w")
        target.write  (code)
        target.close  ()
Exemplo n.º 23
0
import _TFL.Package_Namespace
import _TFL.Record

from   timeit                     import default_timer as _timer
from   fnmatch                    import fnmatch

import doctest
import importlib
import logging
import sys
import subprocess
import fnmatch

TFL.Package_Namespace._check_clashes = False ### avoid spurious ImportErrors

_app_test_pat = Regexp (r"^ *__App_Tests__ *=", re.MULTILINE)

def has_app_test (fn) :
    with open (fn, "rb") as f :
        code = pyk.decoded (f.read ())
    return _app_test_pat.search (code)
# end def has_app_test

def import_module (path) :
    fn = Filename (path)
    mn = fn.base
    md = fn.directory or "./"
    with TFL.Context.list_push (sys.path, md, 0) :
        result = importlib.import_module (mn)
        result.__App_Tests_Dir__ = md
        return result
Exemplo n.º 24
0
    ( ( "(?:"
      , "|".join ((_poland_geo_ndc, _poland_mobile_ndc))
      , ")"
      )
    )

### https://en.wikipedia.org/wiki/Local_conventions_for_writing_telephone_numbers
### Map of regular expressions for matching phone numbers,
### indexed by country code
ndc_sn_matcher_map = \
    {    "1" : ### North America (US, CA, ...)
               ### https://en.wikipedia.org/wiki/Local_conventions_for_writing_telephone_numbers#United_States.2C_Canada.2C_and_other_NANP_countries
               ### https://en.wikipedia.org/wiki/North_American_Numbering_Plan
        Multi_Regexp
          ( Regexp
              ( r"\(" + r"(?P<ndc>[0-9]{3})" + r"\) ?"
                r"(?P<sn>[0-9]{3}[- .]?[0-9]{4})?"
              )
          , Regexp
              ( r"(?P<ndc>[0-9]{3})[- .]"
                r"(?P<sn>[0-9]{3}[- .]?[0-9]{4})?"
              )
          )
    , "351" : ### Portugal
              ### https://en.wikipedia.org/wiki/Local_conventions_for_writing_telephone_numbers#Portugal
        Multi_Regexp
          ( Regexp
              ( r"(?P<ndc>2[12]|9[1236])[- ]?"
                r"(?P<sn>\d{2}[- ]?\d{2}[- ]?\d{3})?"
              )
          , Regexp
              ( r"(?P<ndc>256|309)[- ]?"
class NDC(TFL.Meta.Object):

    ### Want three integer columns, two string columns
    _converters = (_str_int, int, int, _decoded, _decoded)

    ### DRY info
    _info_cleaner = Re_Replacer("^Area code for ", "")
    _info_map     = \
        {  "650" : "Mobile (Telering)"
        ,  "660" : "Mobile (Hutchison 3G/3)"
        ,  "664" : "Mobile (A1)"
        ,  "676" : "Mobile (T-Mobile Austria)"
        ,  "677" : "Mobile (HoT)"
        ,  "680" : "Mobile (BoB)"
        ,  "681" : "Mobile (yesss!)"
        ,  "688" : "Mobile (Previously Tele2)"
        ,  "699" : "Mobile (Previously Orange, yesss!)"
        }

    ### rtr.at specifies 67, 68, 69 as NDCs but these are not complete — the
    ### actual NDCs look like 676, 688, or 699
    _ndc_add_digit = Regexp("^6[789]$")

    ### Shorten usage to one word
    _usage_map    = \
        { "local network code" : "geographic"
        , "mobile services"    : "mobile"
        , "service number"     : "service"
        , "routing number"     : "routing"
        }

    def __init__(self, ndc, max_len, min_len, usage, info):
        self.ndc = ndc
        self.max_len = max_len
        self.min_len = min_len
        self.usage = usage
        self.info = info

    # end def __init__

    @classmethod
    def from_xls_row(cls, row):
        try:
            ndc, max_len, min_len, usage, info = tuple \
                (c (x.value) for c, x in zip (cls._converters, row))
        except Exception:
            pass
        else:
            if cls._ndc_add_digit.match(ndc):
                for i in range(10):
                    ndc_x = ndc + str(i)
                    yield cls._from_row(ndc_x, max_len, min_len, usage, info)
            else:
                yield cls._from_row(ndc, max_len, min_len, usage, info)

    # end def from_xls_row

    @classmethod
    def _from_row(cls, ndc, max_len, min_len, usage, info):
        ndc_len = len(ndc)
        usage = cls._usage_map.get(usage, usage)
        info = cls._info_cleaner(cls._info_map.get(ndc, info))
        if not info:
            info = usage.capitalize()
        return cls(ndc, max_len - ndc_len, min_len - ndc_len, usage, info)

    # end def _from_row

    def __repr__(self):
        return "%s (%s, %s)" % (self, self.min_len, self.max_len)

    # end def __repr__

    def __str__(self):
        return "%s [%s]" % (self.ndc, self.info)
Exemplo n.º 26
0
class PMPP (TFL.Meta.Object) :
    """Poor-Man's Pre-Processor: rewrite a file according to preprocessor
       comments.

       >>> pp     = PMPP ("TESTTAG")
       >>> source = '''Line before start-tag
       ...    Indented line before start-tag
       ...    # _TESTTAG_LINE_ single tagged line
       ...    Another indented line before start-tag
       ...    # _TESTTAG_START_
       ...    # First tagged line
       ...    #     Second tagged line
       ...    # Third tagged line
       ...    # _TESTTAG_ELSE_
       ...    # First line to be removed by PMPP
       ...    #     Second line to be removed by PMPP
       ...    # _TESTTAG_END_
       ...    Line after end-tag
       ... Last line
       ... '''
       >>> for l in pp (pyk.StringIO (source)) :
       ...     print (l, end = "")
       ...
       Line before start-tag
          Indented line before start-tag
          single tagged line
          Another indented line before start-tag
          First tagged line
              Second tagged line
          Third tagged line
          Line after end-tag
       Last line

    """

    comment_pat   = Regexp (r"\s+ (?P<comment> \# \s*)", re.X)
    pattern_pat   = r"^(?P<indent> \s*) \# \s* _%s_%s_ \s*"

    def __init__ (self, tag) :
        pattern_pat   = self.pattern_pat
        self.head_tag = Regexp (pattern_pat % (tag, "START"), re.X)
        self.else_tag = Regexp (pattern_pat % (tag, "ELSE"),  re.X)
        self.tail_tag = Regexp (pattern_pat % (tag, "END"),   re.X)
        self.line_tag = Regexp (pattern_pat % (tag, "LINE"),  re.X)
    # end def __init__

    def rewrite (self, fname, target_dir) :
        target = Filename (target_dir, fname)
        f      = open     (fname,  "r")
        o      = open     (target, "w")
        print ("Processing %s" % (target, ))
        for l in self (f) :
            o.write (l)
    # end def rewrite

    def __call__ (self, source) :
        head_tag    = self.head_tag
        else_tag    = self.else_tag
        tail_tag    = self.tail_tag
        line_tag    = self.line_tag
        comment_pat = self.comment_pat
        comment     = "# "
        for l in source :
            if not head_tag.match (l) :
                if line_tag.match (l) :
                    ### return text without line-tag
                    yield line_tag.sub (r"\g<indent>", l, 1)
                else :
                    ### return untagged text unchanged
                    yield l
            else :
                l = next (source)
                if comment_pat.match (l) :
                    comment = comment_pat.comment
                while not (else_tag.match (l) or tail_tag.match (l)) :
                    ### return text between start-tag and else- or tail-tag
                    ### without the leading comment
                    yield l.replace (comment, "", 1)
                    l = next (source)
                if else_tag.match (l) :
                    ### skip over text between else- and tail-tag
                    while not tail_tag.match (l) :
                        l = next (source)
Exemplo n.º 27
0
import _MOM.import_MOM
import _MOM._Graph.Relation

from _TFL._D2 import Cardinal_Direction as CD
from _TFL.Math_Func import sign
from _TFL.multimap import mm_list
from _TFL.predicate import dusplit
from _TFL.pyk import pyk
from _TFL.Regexp import Regexp, re

import _TFL.Decorator
import _TFL.Sorted_By
import _TFL._Meta.Object
import _TFL._Meta.Once_Property

_word_sep = Regexp("([^A-Za-z0-9])")


class Rel_Placer(TFL.Meta.Object):
    """Place attachement points of all relations of an Entity."""
    @pyk.adapt__bool__
    @pyk.adapt__str__
    class Dir_Placer(TFL.Meta.Object):
        """Placer for relations in one cardinal direction"""

        _offset_7 = [0.125, 0.250, 0.375, 0.500, 0.625, 0.750, 0.875]
        _offset_map     = \
            { 1         : [0.500]
            , 2         : [0.250, 0.750]
            , 3         : [0.250, 0.500, 0.750]
            , 4         : [0.125, 0.375, 0.625, 0.875]
Exemplo n.º 28
0
    ( "ignore", "in 3.x, __getslice__ has been removed; use __getitem__")

from   PIL import Image, ImageDraw, ImageFile, ImageFont, ExifTags

try :
    import plumbum
except ImportError :
    plumbum = None

### http://mail.python.org/pipermail/image-sig/1999-August/000816.html
### to avoid exception
###     IOError: encoder error -2 when writing image file

ImageFile.MAXBLOCK = 1000000 # default is 64k

_rotate_pat = Regexp (r"Rotate\s+(?P<angle>\d+)\s+CW")

def convert_one \
        ( src, name, i_size, t_size, holder, year, font, imp, thp
        , format, color, x_off, y_off
        , temp_dir = None
        ) :
    f_src = fix_rotation (src, temp_dir)
    im    = Image.open   (f_src)
    th    = im.copy      ()
    im.thumbnail (i_size, Image.ANTIALIAS)
    th.thumbnail (t_size, Image.ANTIALIAS)
    if holder :
        xo   = x_off if x_off > 0 else im.size [0] + x_off
        yo   = y_off if y_off > 0 else im.size [1] + y_off
        draw = ImageDraw.Draw (im)
Exemplo n.º 29
0
class TFL_SAG_Command (TFL.Command.Root_Command) :
    """Auto-generate sphinx stub documentation pages."""

    _real_name              = "Command"
    _rn_prefix              = "TFL_SAG_"

    min_args                = 1

    mod_skip                = \
        { "_MOM.Babel" # module not yet documented (low priority)
        # ### obsolete
        , "_TFL.Assertion", "_TFL.B64", "_TFL.Class_Proxy", "_TFL.Command_Line"
        , "_TFL.Date_Time", "_TFL.Filesystem"
        , "_TFL.Latex_Stream", "_TFL.NO_List", "_TFL.object_globals"
        , "_TFL.Plugin", "_TFL.Plugin_Packager"
        , "_TFL.PL_Dict", "_TFL.PL_List", "_TFL.Sync_File"
        }

    mod_skip_pat            = Regexp \
        ( r"__test__|(?:^_test_)|(?:^setup.py$)|(?:^_pyk[23].py[co]?$)"
        )

    pkg_init_pat            = Regexp ("(^|/)__init__.py[co]?$")

    pns_skip                = \
        { "__doc__" # not a package anyway
        # ### not yet documented (high priority)
        , "GTW.OMP.PAP.E164", "GTW.OMP.SRM"
        , "GTW.MF3", "GTW.RST", "GTW.Werkzeug"
        , "MOM.EMS", "MOM.DBW"
        , "ReST"
        # ### not yet documented (low priority)
        , "GTW.OMP.DNS", "GTW.OMP.NET"
        , "ATAX", "CAL", "SKY", "LNX", "PMA", "TFL.Babel"
        , "TFL.DRA", "TFL.FMW", "TFL.SDG"
        }

    pns_skip_modules        = \
        { "GTW", "GTW.OMP" # modules not yet documented (high priority)
        }

    pns_skip_pat            = Regexp \
        ( r"(?:^__doc__$)|(?:\.(?:_?Test|_?tests|__test__|TKT|UI)$)"
        )

    _args                   = \
        ( "pkg_name:P?Name(s) of package(s) implementing package namespace(s)"
        ,
        )

    _defaults               = dict \
        ( doc_base          = "__doc__/source"
        )

    _opts                   = \
        ( "-verbose:B"
        ,
        )

    _rank_default           = 500
    _ranks                  = dict \
        ( MOM               = 100
        , GTW               = 150
        , JNJ               = 200
        , TFL               = 300
        )

    _ranks_by_prefix         = \
        { "GTW.OMP"         :
            [ "Auth", "PAP", "SWP", "EVT"]
        , "GTW.OMP.PAP"     :
            [ "Subject"
            , "Person"
            , "Group", "Legal_Entity", "Company", "Association", "Adhoc_Group"
            , "Property"
            , "Address", "Email", "Phone"
            ]
        , "MOM"             :
            [ "Entity", "Object", "Link", "E_Type_Manager"
            , "Q_Exp", "SQ", "App_Type", "Scope"
            , "Meta", "Prop", "Attr", "Pred", "SCM", "EMS", "DBW"
            ]
        , "MOM.Attr"        :
            [ "Type", "Kind", "Spec", "Manager"]
        , "MOM.Pred"        :
            [ "Type", "Kind", "Spec", "Manager"]
        , "TFL"             : ["Package_Namespace"]
        , "TFL.Meta"        :
            [ "Object", "M_Class", "M_Auto_Update_Combined", "M_Auto_Combine"
            , "Property", "Once_Property", "Lazy_Method"
            ]
        }

    _stub_mod_template      = """\
.. automatically generated by TFL.sphinx_autogen, don't change manually

Module `%(b_name)s`
-------------------------------------------------------------------------------

.. automodule:: %(m.__name__)s
  :members: %(x_members)s
  :special-members:
"""

    _stub_pns_template      = """\
.. automatically generated by TFL.sphinx_autogen, don't change manually

Package-NS `%(b_name)s`
-------------------------------------------------------------------------------

.. automodule:: %(m._Package_Namespace__module_name)s
"""
    _stub_pns_template_graph = """\
.. image:: /graphs/%(q_name)s.*

"""

    _stub_pns_template_doc = """\
.. automodule:: %(m._Package_Namespace__module_name)s.__doc__
"""

    _stub_pns_template_toc = """\
.. toctree::
  :glob:
"""

    class Doc_Base (TFL.Command.Rel_Path_Option) :
        """Base directory of documentation sources."""

        auto_split   = ""
        single_match = True
        skip_missing = False
        _base_dirs   = ("$lib_dir", )

    # end class Doc_Base

    @Class_and_Instance_Once_Property
    def ranks (self) :
        result = defaultdict (lambda : self._rank_default, self._ranks)
        for p, rs in pyk.iteritems (self._ranks_by_prefix) :
            result.update ((".".join ([p, r]), i) for i, r in enumerate (rs))
        return result
    # end def ranks

    def handler (self, cmd) :
        allow = set ()
        with TFL.Context.attr_let (self, cmd = cmd, allow = allow) :
            doc_base = cmd.doc_base
            for pn in cmd.argv :
                allow.add (pn)
                self._handle_package (pn, doc_base)
    # end def handler

    def _handle_package (self, pn, doc_base) :
        pkg = __import__ (pn)
        try :
            pns = pkg.__PNS__
        except AttributeError :
            if pn not in self.allow :
                print ("Package %s doesn't implement a package namespace" % pn)
            return
        if pns.__name__ in self.pns_skip and not pn in self.allow :
            return
        b_name  = pns.__name__.split (".") [-1]
        self.allow.add (pns.__name__)
        self._handle_pns (None, pns, b_name, doc_base)
    # end def _handle_package

    def _handle_package_inner (self, pns, doc_base) :
        if self.cmd.verbose :
            print (pns.__name__)
        pns._Import_All (self.mod_skip_pat)
        n_mod = 0
        n_pns = 0
        skip_modules = pns.__name__ in self.pns_skip_modules
        for m in pns.MODULES :
            b_name  = m.__name__.split (".") [-1]
            is_pns  = getattr (m, "__is_PNS__", False)
            stubber = self._stub_pns if is_pns else self._stub_mod
            want    = is_pns or not skip_modules
            if want and stubber (pns, m, b_name, doc_base) :
                n_mod  += not is_pns
                n_pns  += bool (is_pns)
        return n_mod, n_pns
    # end def _handle_package_inner

    def _handle_pns \
            (self, outer, inner, b_name, doc_base) :
        n_mod, n_pns = self._handle_package_inner (inner, doc_base)
        scope        = Scope \
            ( b_name = b_name
            , m      = inner
            , q_name = "_".join (inner.__name__.split ("."))
            )
        parts        = [self._stub_pns_template % scope]
        doc_path     = sos.path.join \
            (sos.path.dirname (inner.__file__), "__doc__.py")
        graph_mod    = getattr (inner, "graph", None)
        if graph_mod is not None :
            try :
                self._make_graph (inner, graph_mod, scope.q_name, doc_base)
            except Exception as exc :
                logging.exception (doc_path)
            else :
                parts [0] += (self._stub_pns_template_graph % scope)
        if sos.path.isfile (doc_path) :
            parts [0] += (self._stub_pns_template_doc % scope)
        if n_mod + n_pns :
            parts.append (self._stub_pns_template_toc)
            if n_mod :
                parts.append ("  %s/M_[0-9]*\n" % b_name)
            if n_pns :
                parts.append ("  %s/P_[0-9]*\n" % b_name)
        k      = inner.__name__.split (".") [-1]
        s_body = "\n".join (parts)
        s_name = self._ranked_file_name (outer, k, "P")
        with self._open_stub (doc_base, outer, s_name) as f :
            f.write (pyk.encoded (s_body))
    # end def _handle_pns

    def _make_graph (self, inner, graph_mod, q_name, doc_base) :
        import plumbum
        py    = plumbum.local [b"python"]
        m_nam = graph_mod.__name__
        if "." not in m_nam :
            m_nam = ".".join ((graph_mod.__PNS__.__PKG__.__name__, m_nam))
        g_dir = "%s/%s" % (doc_base, "graphs")
        cmd   = py ["-m", m_nam, "-all", "-dir", g_dir, "-name", q_name, "-png"]
        if self.cmd.verbose :
            print (cmd)
        cmd ()
    # end def _make_graph

    @TFL.Contextmanager
    def _open_stub (self, doc_base, pns, name) :
        dir = doc_base
        if pns is not None :
            dir = sos.path.join (dir, * pns.__name__.split ("."))
        if not sos.path.isdir (dir) :
            if sos.path.exists (dir) :
                raise IOError ("Path %s exists but isn't a directory" % dir)
            sos.mkdir_p (dir)
        with open (sos.path.join (dir, name + ".rst"), "wb") as f:
            yield f
    # end def _open_stub

    def _ranked_file_name (self, pns, b_name, prefix) :
        q_name = b_name if pns is None else ".".join ((pns.__name__, b_name))
        rank   = self.ranks [q_name]
        result = "%s_%3.3d_%s" % (prefix, rank, b_name)
        return result
    # end def _ranked_file_name

    def _stub_mod (self, pns, m, b_name, doc_base) :
        if self.mod_skip_pat.search (m.__name__) or m.__name__ in self.mod_skip:
            return False
        x_members = ", ".join (getattr (m, "__sphinx__members", ()))
        s_body    = self._stub_mod_template % Scope \
            ( m         = m
            , b_name    = b_name
            , x_members = x_members
            )
        s_name    = self._ranked_file_name (pns, b_name, "M")
        with self._open_stub (doc_base, pns, s_name) as f :
            f.write (pyk.encoded (s_body))
        return True
    # end def _stub_mod

    def _stub_pns (self, outer, m, m_b_name, doc_base) :
        inner  = m.__PNS__
        b_name = inner.__name__.split (".") [-1]
        i_name = inner.__name__
        if ( self.pns_skip_pat.search (i_name) or i_name in self.pns_skip
           ) and not i_name in self.allow :
            return False
        self._handle_pns (outer, inner, b_name, doc_base)
        return True
Exemplo n.º 30
0
class Calc(TFL.Meta.Object):
    """Model a CSS calc expression."""

    _expr_pat = Regexp(r"(?: |[*/])")
    _product_pat = Regexp(r"[*/]")
    _sub_pat = Regexp(r" - ")

    def __init__(self, *args):
        as_text = str
        self.args = args
        self.value = " ".join(as_text(a) for a in args)

    # end def __init__

    def __add__(self, rhs):
        product_p = self._product_pat.search(self.value)
        lhs = self if product_p else self.value
        return self.__class__(lhs, "+", rhs)

    # end def __add__

    def __mul__(self, rhs):
        expr_p = self._expr_pat.search(self.value)
        lhs = self if expr_p else self.value
        return self.__class__(lhs, "*", rhs)

    # end def __mul__

    def __radd__(self, rhs):
        value = self.value
        product_p = self._product_pat.search(value)
        sub_p = self._sub_pat.search(value)
        lhs = self if product_p or sub_p else value
        return self.__class__(rhs, "+", lhs)

    # end def __radd__

    def __repr__(self):
        return repr(str(self))

    # end def __repr__

    def __rmul__(self, rhs):
        expr_p = self._expr_pat.search(self.value)
        lhs = self if expr_p else self.value
        return self.__class__(rhs, "*", lhs)

    # end def __rmul__

    def __rsub__(self, rhs):
        expr_p = self._expr_pat.search(self.value)
        lhs = self if expr_p else self.value
        return self.__class__(rhs, "-", lhs)

    # end def __rsub__

    def __sub__(self, rhs):
        expr_p = self._expr_pat.search(self.value)
        lhs = self if expr_p else self.value
        return self.__class__(lhs, "-", rhs)

    # end def __sub__

    def __truediv__(self, rhs):
        expr_p = self._expr_pat.search(self.value)
        lhs = self if expr_p else self.value
        return self.__class__(lhs, "/", rhs)

    # end def __truediv__

    def __str__(self):
        return "calc(%s)" % (self.value, )