<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>funcptr - python</title>
    <subtitle>An engineer&#x27;s technical notebook</subtitle>
    <link rel="self" type="application/atom+xml" href="https://funcptr.net/language/python/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://funcptr.net/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2021-02-15T00:00:00+00:00</updated>
    <id>https://funcptr.net/language/python/atom.xml</id>
    <entry xml:lang="en">
        <title>Python Packaging and Distribution</title>
        <published>2018-05-21T14:00:00+00:00</published>
        <updated>2018-05-21T14:00:00+00:00</updated>
        
        <author>
          <name>
            
              Delta Regeer
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://funcptr.net/2018/python-packaging/"/>
        <id>https://funcptr.net/2018/python-packaging/</id>
        
        <content type="html" xml:base="https://funcptr.net/2018/python-packaging/">&lt;p&gt;There&#x27;s been many a discussion online related to a variety of tools related to
Python packaging and distribution. There is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pip.pypa.io&quot;&gt;pip&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.pipenv.org&quot;&gt;pipenv&lt;&#x2F;a&gt; and
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;poetry.eustace.io&quot;&gt;poetry&lt;&#x2F;a&gt; that have been the tools under discussion.&lt;&#x2F;p&gt;
&lt;p&gt;As an open source maintainer as part of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pylonsproject.org&quot;&gt;Pylons Project&lt;&#x2F;a&gt;, while I would
love to be writing code I end up spending a lot of time dealing with user
questions around packaging&#x2F;distributing their source code using the software
I&#x27;ve helped build, and as we move forward myself and other maintainers were
wondering if we were actually helping users move forward in the best way
possible using best of breed tools.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-201805tooldiscussionpyramid-1&quot;&gt;&lt;a href=&quot;#fn-201805tooldiscussionpyramid&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As the Python community has moved from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20180527214739&#x2F;http:&#x2F;&#x2F;setuptools.readthedocs.io&#x2F;en&#x2F;latest&#x2F;easy_install.html#easy-install&quot;&gt;easy_install&lt;&#x2F;a&gt; to pip, we too have
kept the documentation up to date. We went from &lt;code&gt;python setup.py develop&lt;&#x2F;code&gt; to
&lt;code&gt;pip install -e .&lt;&#x2F;code&gt; to create editable installs of local projects, and try to
let people know the pitfalls of using both easy_install and pip in the same
project (mostly with an answer that falls in line with: remove your virtual
environment and start over, just use pip).&lt;&#x2F;p&gt;
&lt;p&gt;As part of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;trypyramid.com&quot;&gt;Pyramid&lt;&#x2F;a&gt; we have developed and maintain various different
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cookiecutter.readthedocs.io&#x2F;en&#x2F;latest&#x2F;&quot;&gt;cookiecutter&lt;&#x2F;a&gt; templates, and our goal is to attempt to provide templates
that are both useful, but also follow best practices that are being adopted
within the community at large so that newcomers can use their existing
skills&#x2F;knowledge and those that are starting with us walk away with a knowledge
and experience that applies not just to development of Pyramid applications,
but also applies to the broader community as a whole.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pip&quot;&gt;pip&lt;&#x2F;h2&gt;
&lt;p&gt;Pip is a great tool that has simplified installation of packages, it supports
using binary distributions named &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;pypa&#x2F;wheel&quot;&gt;wheels&lt;&#x2F;a&gt; and has a way to easily install
software from the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pypi.org&quot;&gt;Python Packaging Index&lt;&#x2F;a&gt;. It has a rather naive
dependency resolution process, but for the most part it works and works well.
It replaced easy_install as the tool to use for installing packages.&lt;&#x2F;p&gt;
&lt;p&gt;While you can use a &lt;code&gt;requirements.txt&lt;&#x2F;code&gt; file with pip to install a &quot;blessed&quot;
list of software there is no good way to &quot;lock&quot; the dependencies of
dependencies without manually adding it to the list of requirements. This ends
up making it very difficult to manage, and it is very difficult to know that
what has been tested is what the user is actually going to get because packages
may be updated at anytime, and re-creating the same exact environment is
difficult and fraught with errors.&lt;&#x2F;p&gt;
&lt;p&gt;This is where &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;pypa&#x2F;pipfile&quot;&gt;Pipfile&lt;&#x2F;a&gt; is supposed to help. This is a project to add a
new, more descriptive requirements file, as well as allowing for a lockfile
that would lock not just your primary packages you have listed, but also all
dependencies of dependencies all the way down the tree. This helps with
reproducibility and allows for the same installation on two different systems
to have the exact same software&#x2F;dependencies installed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pipenv&quot;&gt;pipenv&lt;&#x2F;h2&gt;
&lt;p&gt;While pip is a great tool, and with the Pipfile changes it would allow for
locking of dependencies, there is one more puzzle piece missing. When
installing packages while you can install them into the global namespace, the
recommended way is to install all packages for a particular tool&#x2F;project into a
virtual environment.&lt;&#x2F;p&gt;
&lt;p&gt;Normally you&#x27;d invoke &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;virtualenv.pypa.io&#x2F;en&#x2F;stable&#x2F;&quot;&gt;virtualenv&lt;&#x2F;a&gt;, to create this environment and then
you&#x27;d make sure to install all packages within it, thereby isolating it from
the rest of the system.&lt;&#x2F;p&gt;
&lt;p&gt;pipenv automates this for you, as well as using &lt;code&gt;Pipfile&lt;&#x2F;code&gt; it also supports
locking using &lt;code&gt;Pipfile.lock&lt;&#x2F;code&gt; and provides a bunch of tooling around
adding&#x2F;removing dependencies from a local project.&lt;&#x2F;p&gt;
&lt;p&gt;pipenv allows you to easily create an environment and manage dependencies, but
it makes no effort to solve the problem of distributing and building a package
that may be installed by third parties.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;poetry&quot;&gt;poetry&lt;&#x2F;h2&gt;
&lt;p&gt;Poetry is a similar project to pipenv, with a major difference being that it
was built to help with distributing&#x2F;developing applications and building a
distributable package that may then be installed using pip.&lt;&#x2F;p&gt;
&lt;p&gt;Instead of using a &lt;code&gt;Pipfile&lt;&#x2F;code&gt; it uses a recently standardised &lt;code&gt;pyproject.toml&lt;&#x2F;code&gt;
file instead. Like pipenv it also supports locking, and it provides tooling
around adding&#x2F;removing dependencies as well as managing what versions are
required.&lt;&#x2F;p&gt;
&lt;p&gt;Ultimately those dependencies are going to end up as metadata in a
distributable package.&lt;&#x2F;p&gt;
&lt;p&gt;Poetry makes it easier to manage a software development project, whether that
is for an application using various libraries for internal use, or for
libraries that are going to be distributed to other developers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-divide&quot;&gt;The divide&lt;&#x2F;h2&gt;
&lt;p&gt;This is where the divide really starts, while you can use pipenv with a
standard &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;setuptools.readthedocs.io&#x2F;en&#x2F;latest&#x2F;&quot;&gt;setuptools&lt;&#x2F;a&gt; project, any dependencies you add to the Pipfile
using pipenv&#x27;s tooling will not be listed as a dependencies for your project
when you distribute it, this either means you need to duplicate the list in
both &lt;code&gt;setup.py&lt;&#x2F;code&gt; as well as the &lt;code&gt;Pipfile&lt;&#x2F;code&gt;, or you have to add your current
project as an editable install within your &lt;code&gt;Pipfile&lt;&#x2F;code&gt; which means your &lt;code&gt;Pipfile&lt;&#x2F;code&gt;
is now not as easily distributable.&lt;&#x2F;p&gt;
&lt;p&gt;There are work-arounds that people have used, such as having &lt;code&gt;setup.py&lt;&#x2F;code&gt; read a
&lt;code&gt;requirements.txt&lt;&#x2F;code&gt;, so that you could have all your requirements listed in a
text file, and not in &lt;code&gt;setup.py&lt;&#x2F;code&gt;, but asking to do the same with a &lt;code&gt;Pipfile&lt;&#x2F;code&gt; in
pipenv was met with a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20201020045235&#x2F;https:&#x2F;&#x2F;github.com&#x2F;pypa&#x2F;pipenv&#x2F;issues&#x2F;209#issuecomment-332553113&quot;&gt;&quot;Do not do this.&quot;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;poetry explicitly allows you to add dependencies in one place, and those
dependency listings are then automatically inserted into the package metadata
that is created when you build your distributable package.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-two-use-cases&quot;&gt;The two use cases&lt;&#x2F;h2&gt;
&lt;p&gt;There are two competing use cases, one is the deployment of software packages
and being able to run them, but not as a developer, the other is a developer of
software packages that needs to define dependencies for the project to run.&lt;&#x2F;p&gt;
&lt;p&gt;pipenv solves the deployment case. If I was a user I could very simply grab a
known good &lt;code&gt;Pipfile.lock&lt;&#x2F;code&gt; and use pipenv to install a known good set of
software, this is great when I am deploying a project. It is the use case that
many in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.pypa.io&#x2F;en&#x2F;latest&#x2F;&quot;&gt;Python Packaging Authority&lt;&#x2F;a&gt; also seem to be optimizing for.&lt;&#x2F;p&gt;
&lt;p&gt;The other use case is for developers that are building new software, either by
using a list of existing packages and deploying privately, or people developing
software for other developers to be published on the Python Packaging Index.&lt;&#x2F;p&gt;
&lt;p&gt;This latter group of people is under represented due to it likely being much
smaller, and existing tools like &lt;code&gt;setuptools&lt;&#x2F;code&gt; and &lt;code&gt;setup.py&lt;&#x2F;code&gt; already providing
a &quot;good enough&quot; experience. Innovation in this area is something that readily
needs to be improved upon to make it easier to create new libraries&#x2F;packages
that follow best practices. The amount of copy and pastes people have done for
adding a &lt;code&gt;setup.py&lt;&#x2F;code&gt; to their projects or to make something work is long. It&#x27;s
all a little bit of black magic, and there is a great many things that have
been carried over because of cargo cult programming.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;explicit-mentions-by-the-python-packaging-authority&quot;&gt;Explicit mentions by the Python Packaging Authority&lt;&#x2F;h2&gt;
&lt;p&gt;Reading the packaging guide on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;packaging.python.org&#x2F;tutorials&#x2F;managing-dependencies&#x2F;&quot;&gt;managing dependencies&lt;&#x2F;a&gt;, pipenv is the
recommended tool:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;This tutorial walks you through the use of Pipenv to manage dependencies for
an application. It will show you how to install and use the necessary tools
and make strong recommendations on best practices.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;this language, along with what &lt;code&gt;packaging.python.org&lt;&#x2F;code&gt; implies as a URL makes it
difficult as a project maintainer to recommend alternate tools, becuase even if
those tools are superior for the use case we are recommending them for it is
always going to lead to questions from users, such as:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Why are you not using pipenv, the official tool recommended by Python.org?&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;We get similar questions about &lt;code&gt;easy_install&lt;&#x2F;code&gt; vs &lt;code&gt;pip&lt;&#x2F;code&gt; all of the time, as
well as why people should switch, and we can point to various bits of
documentation that explains why pip is a better choice.&lt;&#x2F;p&gt;
&lt;p&gt;If we were to recommend an alternate the appeal to authority that &lt;code&gt;python.org&lt;&#x2F;code&gt;
implies is going to make it much more difficult, and the question will become
&quot;why is the Pylons Project not using recommended tooling?&quot;&lt;&#x2F;p&gt;
&lt;p&gt;poetry is listed as a footnote on that page, alongside &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jazzband&#x2F;pip-tools&quot;&gt;pip-tools&lt;&#x2F;a&gt; and
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ofek&#x2F;hatch&quot;&gt;hatch&lt;&#x2F;a&gt;, and is mentioned only for doing library development, with no
mention of other requirements that may make it a much better tool for
developing locally.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;deployment-is-not-development&quot;&gt;Deployment is not development&lt;&#x2F;h2&gt;
&lt;p&gt;If I am using pipenv with a non-installable project (no setup.py) I end up
having to figure out how to get the code, and the &lt;code&gt;Pipfile&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;Pipfile.lock&lt;&#x2F;code&gt; to
my environment I am deploying into. pipenv&#x27;s install provides a way to make
sure to only install if the &lt;code&gt;Pipfile.lock&lt;&#x2F;code&gt; is up to date or otherwise will fail
to continue. If you are using a local project though, and it uses &lt;code&gt;setup.py&lt;&#x2F;code&gt;
the only way that the &lt;code&gt;Pipfile.lock&lt;&#x2F;code&gt; will contain any sub-dependencies of your
&lt;code&gt;setup.py&lt;&#x2F;code&gt; project is if you install it as &lt;code&gt;editable&lt;&#x2F;code&gt;. Otherwise
sub-dependencies are not locked.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-201805subdepends-1&quot;&gt;&lt;a href=&quot;#fn-201805subdepends&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If I am using poetry I get an pip installable project, but it doesn&#x27;t contain
any hard pins or lock files. I&#x27;d have to distribute &lt;code&gt;pyproject.lock&lt;&#x2F;code&gt; as well as
my wheel. This gets me a little closer, but still no lock file that includes my
newly produced wheel, and has all of its dependencies locked.&lt;&#x2F;p&gt;
&lt;p&gt;The Python Packaging Authority based on Twitter conversations with its members
and the documentation on &lt;code&gt;packaging.python.org&lt;&#x2F;code&gt; suggest using pipenv for
development. pipenv is particular ill-suited for development if the goal is to
create a package to be deployed to production. With two locations to define
dependencies it leaves people scratching their heads as to which is canonical,
and if a dependency is added to &lt;code&gt;Pipfile&lt;&#x2F;code&gt; but not &lt;code&gt;setup.py&lt;&#x2F;code&gt; it may leave a
developer thinking their package is ready for distribution when in reality it
is missing a dependency that is required to run&#x2F;use said distribution.&lt;&#x2F;p&gt;
&lt;p&gt;At this point using both projects seems like a win-win. Use poetry to
build&#x2F;develop a package, then use pipenv in the integration phase to create a
&lt;code&gt;Pipfile.lock&lt;&#x2F;code&gt; that is used to deploy in production. This way you get the best
of both worlds. A great tool that can help you register entry points and
another that can help you with deploying a known good set of dependencies.&lt;&#x2F;p&gt;
&lt;p&gt;Interestingly, even the pipenv docs seem to agree that it is a deployment tool:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Specify your target Python version in your Pipfile’s [requires] section.
Ideally, you should only have one target Python version, as this is a
deployment tool.&lt;&#x2F;p&gt;
&lt;p&gt;-- &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.pipenv.org&#x2F;basics&#x2F;#general-recommendations-version-control&quot;&gt;Pipenv - General Recommendations &amp;amp; Version Control&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Use pipenv if you have a script that requires a couple of dependencies and
doesn&#x27;t need all of the extra overhead of packaging metadata&#x2F;packaging. Use
poetry if you want to build a distributable project that can easily be deployed
by others, and use both if you develop a project and need a known good
environment to deploy.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;in-summary&quot;&gt;In summary&lt;&#x2F;h2&gt;
&lt;p&gt;There will likely never be a time that one single tool is considered good
enough, and competition between tools is a way to keep advancing forward.
Packaging in the Python community for a long time has been difficult. Wheels
has made things a little better. pip has made management of installing new
packages easier and improved upon easy_install. Here&#x27;s to the next evolution.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Now, can we talk about standardising on &lt;code&gt;pyproject.toml&lt;&#x2F;code&gt; since that is already
where &quot;project&quot; metadata needs to go, might as well re-use the name instead of
having two different names&#x2F;files. Oh, and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.python.org&#x2F;dev&#x2F;peps&#x2F;pep-0517&#x2F;&quot;&gt;PEP 517&lt;&#x2F;a&gt; can&#x27;t come soon enough
so that alternate tools like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;flit.readthedocs.io&#x2F;en&#x2F;latest&#x2F;&quot;&gt;flit&lt;&#x2F;a&gt; can be used instead of
setuptools&#x2F;&lt;code&gt;setup.py&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-201805tooldiscussionpyramid&quot;&gt;
&lt;p&gt;We created an issue named &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Pylons&#x2F;pyramid&#x2F;issues&#x2F;3270&quot;&gt;Support poetry,
flit, pipenv, or ...?&lt;&#x2F;a&gt; that attempts to go over the pros and cons of the
various tools and how we currently support our users in our documentation on
building projects using pyramid, including how to create a project that is
distributable.  Pyramid heavily uses &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;setuptools.readthedocs.io&#x2F;en&#x2F;latest&#x2F;pkg_resources.html&quot;&gt;&lt;code&gt;pkg_resources&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; and entry
points.  The way to register the entry points is to have an installable
package. The framework is flexible enough that there is no requirement for
entry points, but at that point you are in territory where the default
tooling provided by the project will not work, and some of the convenience
tools&#x2F;functionality that Pyramid provides it&#x27;s users&#x2F;developers is not
available. &lt;a href=&quot;#fr-201805tooldiscussionpyramid-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-201805subdepends&quot;&gt;
&lt;p&gt;See documentation for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.pipenv.org&#x2F;basics&#x2F;#editable-dependencies-e-g-e&quot;&gt;Editable Dependencies (e.g.  &lt;code&gt;-e   .&lt;&#x2F;code&gt;)&lt;&#x2F;a&gt; which as of this writing states: &lt;blockquote&gt;Sub-dependencies are &lt;strong&gt;not&lt;&#x2F;strong&gt; added to the Pipfile.lock if you leave the -e option out.&lt;&#x2F;blockquote&gt; &lt;a href=&quot;#fr-201805subdepends-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Build numbers in binaries using waf</title>
        <published>2014-06-10T17:32:03+00:00</published>
        <updated>2014-06-10T17:32:03+00:00</updated>
        
        <author>
          <name>
            
              Delta Regeer
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://funcptr.net/2014/build-numbers-in-binaries-using-waf/"/>
        <id>https://funcptr.net/2014/build-numbers-in-binaries-using-waf/</id>
        
        <content type="html" xml:base="https://funcptr.net/2014/build-numbers-in-binaries-using-waf/">&lt;p&gt;My build system of choice these days for any C++ project is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;waf.io&quot;&gt;waf&lt;&#x2F;a&gt;. One of
the things I always like havig is the build number included in the final
binary, so that with a simple &lt;code&gt;.&#x2F;binary --version&lt;&#x2F;code&gt; or even &lt;code&gt;.&#x2F;binary&lt;&#x2F;code&gt; the
version is printed that it was built from. This can make it much simpler to
debug any potential issues, especially if fixes may have already been made but
a bad binary was deployed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;setup-the-wscript&quot;&gt;Setup the wscript&lt;&#x2F;h2&gt;
&lt;p&gt;Make sure that your wscript somewhere near the top contains the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;APPNAME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;myapp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;VERSION&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;0.0.0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then in your &lt;code&gt;configure(cfg)&lt;&#x2F;code&gt; add the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cfg.env.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;VERSION&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; VERSION&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cfg.env.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;APPNAME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; APPNAME&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git_version&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt; try_git_version&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; git_version:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cfg.env.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;VERSION&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span&gt; git_version&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;try_git_version()&lt;&#x2F;code&gt; function is fairly simple and looks like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; try_git_version&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;    import&lt;&#x2F;span&gt;&lt;span&gt; os&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;    import&lt;&#x2F;span&gt;&lt;span&gt; sys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    version&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FF5874;&quot;&gt; None&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        version&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; os.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;popen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;git describe --always --dirty --long&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;read&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;strip&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;    except&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; Exception&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; e:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt; e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; version&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It runs &lt;code&gt;git describe --always --dirty --long&lt;&#x2F;code&gt; which will return something
along these lines: &lt;code&gt;401b85f-dirty&lt;&#x2F;code&gt;. If you have any annoted tags, it will
return the tag name as well.&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;code&gt;git&lt;&#x2F;code&gt; is not installed, or it is not a valid &lt;code&gt;git&lt;&#x2F;code&gt; directory, then it will
simply return &lt;code&gt;None&lt;&#x2F;code&gt;. At that point all we have to go on is the &lt;code&gt;VERSION&lt;&#x2F;code&gt;
variable set at the top of the wscript.&lt;&#x2F;p&gt;
&lt;p&gt;Now that we have our configuration environment set up with the &lt;code&gt;VERSION&lt;&#x2F;code&gt; we
want to get that into a file that we can then include in our C++ source code.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;create-a-build-version-h-in-file&quot;&gt;Create a &lt;code&gt;build_version.h.in&lt;&#x2F;code&gt; file&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;ifndef&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;font-style: italic;&quot;&gt; BUILD_VERSION_H_IN_941AD1F24D0A9D&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;define&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;font-style: italic;&quot;&gt; BUILD_VERSION_H_IN_941AD1F24D0A9D&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;char&lt;&#x2F;span&gt;&lt;span&gt; VERSION[] &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;@VERSION@&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;endif&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; &#x2F;* BUILD_VERSION_H_IN_941AD1F24D0A9D *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;add-the-following-to-build-ctx&quot;&gt;Add the following to &lt;code&gt;build(ctx)&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;ctx&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt;features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;subst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt;        source&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;build_version.h.in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt;        target&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;build_version.h&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt;        VERSION&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; ctx.env&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;VERSION&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This uses the substitution feature to transform &lt;code&gt;build_version.h.in&lt;&#x2F;code&gt; into
&lt;code&gt;build_version.h&lt;&#x2F;code&gt;, while inserting the version into the file.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;include-build-version-h-in-your-source-code&quot;&gt;Include &lt;code&gt;build_version.h&lt;&#x2F;code&gt; in your source code&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;build_version.h&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And add something along these lines to your &lt;code&gt;main()&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;std::cerr &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;Version: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; VERSION &lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; std::endl;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will print out the &lt;code&gt;VERSION&lt;&#x2F;code&gt; that has been stored in &lt;code&gt;build_version.h&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;full-example&quot;&gt;Full example&lt;&#x2F;h2&gt;
&lt;p&gt;Check out my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;digitalresistor&#x2F;mdns-announce&quot;&gt;mdns-announce&lt;&#x2F;a&gt; project on Github for an example of how this is
implemented.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Generating stylesheets for pygments</title>
        <published>2011-11-27T00:00:00+00:00</published>
        <updated>2021-02-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Delta Regeer
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://funcptr.net/2011/pygments-stylesheets/"/>
        <id>https://funcptr.net/2011/pygments-stylesheets/</id>
        
        <content type="html" xml:base="https://funcptr.net/2011/pygments-stylesheets/">&lt;p&gt;Update: this blog is no longer using the same technology for deployment as
before, the below information is available for historical reasons.&lt;&#x2F;p&gt;
&lt;hr&gt;
&lt;p&gt;For this blog I am using &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;freewisdom.org&#x2F;projects&#x2F;python-markdown&#x2F;&quot;&gt;Python markdown&lt;&#x2F;a&gt; with the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;pygments.org&#x2F;&quot;&gt;Pygments&lt;&#x2F;a&gt; plugin
that is available. Pygments does all of the code highlighting and outputs the
required &lt;code&gt;span&lt;&#x2F;code&gt; tags and inputs them within the page.&lt;&#x2F;p&gt;
&lt;p&gt;If you were to look at the &lt;code&gt;&amp;lt;div&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;&#x2F;pre&amp;gt;&amp;lt;&#x2F;div&amp;gt;&lt;&#x2F;code&gt; block that is generated
you&#x27;d see something like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;div class=&amp;quot;codehilite&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;def&amp;lt;&#x2F;span&amp;gt; &amp;lt;span class=&amp;quot;nf&amp;quot;&amp;gt;function&amp;lt;&#x2F;span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;(&amp;lt;&#x2F;span&amp;gt;&amp;lt;span class=&amp;quot;n&amp;quot;&amp;gt;var&amp;lt;&#x2F;span&amp;gt;&amp;lt;span class=&amp;quot;o&amp;quot;&amp;gt;=&amp;lt;&#x2F;span&amp;gt;&amp;lt;span class=&amp;quot;bp&amp;quot;&amp;gt;None&amp;lt;&#x2F;span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;):&amp;lt;&#x2F;span&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;if&amp;lt;&#x2F;span&amp;gt; &amp;lt;span class=&amp;quot;n&amp;quot;&amp;gt;var&amp;lt;&#x2F;span&amp;gt; &amp;lt;span class=&amp;quot;ow&amp;quot;&amp;gt;is&amp;lt;&#x2F;span&amp;gt; &amp;lt;span class=&amp;quot;ow&amp;quot;&amp;gt;not&amp;lt;&#x2F;span&amp;gt; &amp;lt;span class=&amp;quot;bp&amp;quot;&amp;gt;None&amp;lt;&#x2F;span&amp;gt;&amp;lt;span class=&amp;quot;p&amp;quot;&amp;gt;:&amp;lt;&#x2F;span&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &amp;lt;span class=&amp;quot;k&amp;quot;&amp;gt;print&amp;lt;&#x2F;span&amp;gt; &amp;lt;span class=&amp;quot;n&amp;quot;&amp;gt;var&amp;lt;&#x2F;span&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&#x2F;pre&amp;gt;&amp;lt;&#x2F;div&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;which is generated from the following snippet of code:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; function&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;var=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FF5874;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; is not&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FF5874;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt; var&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As you see the top css &lt;code&gt;class&lt;&#x2F;code&gt; is &lt;code&gt;codehilite&lt;&#x2F;code&gt;, and then underneath that there
are a bunch of other classes such as &lt;code&gt;k&lt;&#x2F;code&gt;, &lt;code&gt;n&lt;&#x2F;code&gt;, &lt;code&gt;o&lt;&#x2F;code&gt;, and so forth. Those are all
classes that can be styled. Now one could write such a stylesheet by hand or we
can simply use one of the stylesheets that Pygments ships with.&lt;&#x2F;p&gt;
&lt;p&gt;The documentation for Pygments tells you how to get &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;pygments.org&#x2F;docs&#x2F;styles&#x2F;#builtin-styles&quot;&gt;built-in styles&lt;&#x2F;a&gt;, which
is as simple as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt; from&lt;&#x2F;span&gt;&lt;span&gt; pygments.styles&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; get_all_styles&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; styles&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; list&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;get_all_styles&lt;&#x2F;span&gt;&lt;span&gt;())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; styles&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;[&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;monokai&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;manni&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;perldoc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;borland&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;colorful&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;default&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; ...&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;These are all the styles that are available to you the user, now how do we get
the style into an actual &lt;code&gt;.css&lt;&#x2F;code&gt; file that we can link to in our sites HTML
file? We use the &lt;code&gt;pygmentize&lt;&#x2F;code&gt; command line tool:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt;pygmentize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; -f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt; html&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; -S&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt; trac&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; -a&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt; .codehilite&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt; pygments.css&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Feel free to replace &lt;code&gt;trac&lt;&#x2F;code&gt; with any of the styles you have installed on your
system. &lt;code&gt;-f&lt;&#x2F;code&gt; tells it what formatter to use, since we want it to output the css
we ask it to use the HTML formatter, &lt;code&gt;-S&lt;&#x2F;code&gt; tells &lt;code&gt;pygmentize&lt;&#x2F;code&gt; what style to
use, and &lt;code&gt;-a&lt;&#x2F;code&gt; prepends the &lt;code&gt;.codehilite&lt;&#x2F;code&gt; class before every rule (this way we
don&#x27;t pollute the whole CSS namespace with all the aforementioned class&#x27;s such
as &lt;code&gt;k&lt;&#x2F;code&gt;, &lt;code&gt;o&lt;&#x2F;code&gt;, &lt;code&gt;ow&lt;&#x2F;code&gt; and others).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Magic Properties on Google AppEngine</title>
        <published>2010-03-24T02:15:33+00:00</published>
        <updated>2010-03-24T02:15:33+00:00</updated>
        
        <author>
          <name>
            
              Delta Regeer
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://funcptr.net/2010/magic-properties-on-google-appengine/"/>
        <id>https://funcptr.net/2010/magic-properties-on-google-appengine/</id>
        
        <content type="html" xml:base="https://funcptr.net/2010/magic-properties-on-google-appengine/">&lt;p&gt;Update to my previous &lt;a href=&quot;&#x2F;2010&#x2F;auto-updating-properties-in-google-appengine-models&#x2F;&quot;&gt;Google AppEngine auto-updating properties post&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In my last post I was talking about:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;[...] however there is still an issue, for now the MagicProperty is only
updated the first time the property it affects is set&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I fixed that issue, it has a local cache that is added to the model, so if the
value does change, the cache would no longer be valid and the value is
recreated, otherwise the already computed value is returned. There was however
another issue I had to deal with, and that was the fact that the cache was not
being written to the datastore, this meant that upon getting the data back from
the datastore we recomputed it anyway. Now the programmer has to do some extra
work, they have to add a cache unindexed property to the model, and pass it
into the &lt;code&gt;MagicProperty&lt;&#x2F;code&gt; to be used as the caching variable. Within the
&lt;code&gt;save()&lt;&#x2F;code&gt; they have to prime the cache by setting a temporary variable equal to
the to be computed variable just in case the cache variables have not been
primed, this has not yet been documented other than in my SVN history.&lt;&#x2F;p&gt;
&lt;p&gt;We still don&#x27;t allow setting of the magic property, however upon returning from
the datastore it calls &lt;code&gt;make_value_from_datastore&lt;&#x2F;code&gt;, which returns a
&lt;code&gt;_MagicDatastore&lt;&#x2F;code&gt;, as long as we set with an instance of &lt;code&gt;_MagicDatastore&lt;&#x2F;code&gt; it will
allow it to go through, so we can get the value from the datastore without
having to recompute the value.&lt;&#x2F;p&gt;
&lt;p&gt;Read the code for an example on how to use this.&lt;&#x2F;p&gt;
&lt;p&gt;Code is added below, feel free to use it as you wish under the license that is
attached.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;  1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;###&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;  2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; # Copyright (c) 2010 Delta Regeer;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;  3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; #&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;  4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; # Permission to use, copy, modify, and distribute this software for any&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;  5&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; # purpose with or without fee is hereby granted, provided that the above&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;  6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; # copyright notice and this permission notice appear in all copies.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; #&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;  8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; # THE SOFTWARE IS PROVIDED &amp;quot;AS IS&amp;quot; AND THE AUTHOR DISCLAIMS ALL WARRANTIES&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;  9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt; #&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;###&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 17&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; logging&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; hashlib&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; google.appengine.ext&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; db&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 21&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 22&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; MagicProperty&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;prop&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; magic_func=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FF5874;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; cache_prop=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FF5874;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; pass_instance=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FF5874;&quot;&gt;False&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; *args&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; **kw&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 24&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; magic_func:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;        # No pants required.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt; _MagicProperty&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;prop&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; magic_func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; cache_prop&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; pass_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; **&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;kw&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;    else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;        # We are putting some pants on the function.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 29&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;        def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; pants&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;magic_func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt; _MagicProperty&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;prop&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; magic_func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; cache_prop&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; pass_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; **&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;kw&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 31&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; pants&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 33&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFCB8B;&quot;&gt; _MagicDatastore&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 34&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;This is an internal class for _MagicProperty.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 35&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 36&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; val&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 37&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; val&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 38&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 39&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; retval&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 41&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 42&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFCB8B;&quot;&gt; _MagicProperty&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;db&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;Property&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 43&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;MagicProperty which will modify output based on a function that it is given.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 44&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 45&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    This has several ways in which it may be called:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 46&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 47&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    In this example we create the model, no caching is done, so any data that is returned from the datastore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 48&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    will be erased the first time that the MagicProperty is accessed and recomputed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 49&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        class MagicTest(db.Model):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 51&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;            title = db.StringProperty(required=True)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 52&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;            chars = utils.MagicProperty(title, len, required=True)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 53&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 54&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        mytest = MagicTest(title=&amp;quot;It was for the good of the school!&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 55&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        &amp;gt;&amp;gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;print mytest.title&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 57&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        It was for the good of the school!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 58&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        &amp;gt;&amp;gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;print mytest.chars&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 59&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        34&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        mytest = MagicTest.all().get()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 62&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        &amp;gt;&amp;gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;print mytest.title&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        Hello&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 65&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        &amp;gt;&amp;gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;print mytest.chars		&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 66&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        5	# Do note, this is recalculated the first time it is called, as long as title does not change it won&amp;#39;t be recomputed.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 67&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 68&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    In this example we create the model, and we also create a caching property so that even when we get values back &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 69&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    from the datastore we use the cached computed value rather than running the function again. Do note that this requires overriding put()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 70&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    to prime the cache as there is currently no way to specify that certain properties should be &amp;quot;saved&amp;quot; before others.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 71&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 72&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        class MagicTesting(db.Model):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 73&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;            title = db.StringProperty(required=True)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 74&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;            cache = db.UnindexedProperty()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 75&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;            chars = utils.MagicProperty(title, len, cache_prop=cache, required=True)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 76&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 77&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;            def put(self, *args, **kw):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 78&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;                prime_cache = self.chars&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 79&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;                super(MagicTesting).put(*args, **kw)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 80&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 81&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        mytesting = MagicTesting(title=&amp;quot;Get the pocket knife out of my boot.&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 82&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 83&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        &amp;gt;&amp;gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;print mytesting.title&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 84&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        Get the pocket knife out of my boot.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 85&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        &amp;gt;&amp;gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;print mytesting.chars&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 86&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        36&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 87&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 88&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        mytesting = MagicTest.all().get()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 89&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 90&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        &amp;gt;&amp;gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;print mytesting.title&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 91&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        How are you?&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 92&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        &amp;gt;&amp;gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;print mytesting.chars	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 93&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        12	# This is not recomputed so long as the title has not changed, however it uses more datastore space to store a hash.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 94&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 95&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 96&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    Inspired by: &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 97&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    http:&#x2F;&#x2F;appengine-cookbook.appspot.com&#x2F;recipe&#x2F;custom-model-properties-are-cute&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 98&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    http:&#x2F;&#x2F;code.google.com&#x2F;appengine&#x2F;articles&#x2F;extending_models.html&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt; 99&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    http:&#x2F;&#x2F;googleappengine.blogspot.com&#x2F;2009&#x2F;07&#x2F;writing-custom-property-classes.html&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;100&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;101&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;102&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; prop&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; magic_func&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; cache_prop&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; pass_instance&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; *args&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; **kw&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;103&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;104&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        Extra parameters you can give this initializer.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;105&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;106&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;            prop		= Property to be acted upon&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;107&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;            magic_func	= The function to be called when the property is accessed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;108&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;            cache_prop	= The property that can hold our cache, I suggest it is an db.UnindexedProperty() since it just stores sha1 hashes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;109&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;110&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;_MagicProperty&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;__init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; **&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;kw&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;111&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.magic_func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; magic_func&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;112&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.magic_prop&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; prop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;113&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.magic_cache&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cache_prop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;114&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.magic_pass&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; pass_instance&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;115&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;116&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; get_cache_val&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; model_instance&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; class_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;117&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.magic_cache&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; is not&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FF5874;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;118&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.magic_cache.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;__get__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;model_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; class_instance&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;119&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; getattr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;model_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;attr_name&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;orig&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FF5874;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;120&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;121&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; set_cache_val&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; model_instance&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; val&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;122&lt;&#x2F;span&gt;&lt;span&gt;        val&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; hashlib.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;sha1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;val&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;hexdigest&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;123&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;124&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.magic_cache&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; is not&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FF5874;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;125&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span&gt;.magic_cache.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;__set__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;model_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; val&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;126&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;        setattr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;model_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;attr_name&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;orig&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; val&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;127&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;128&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; attr_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;129&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;        # In google.appengine.ex.db there is an explicit warning not to use this method, so we test for it first.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;130&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;._attr_name:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;131&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;_attr_name&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;132&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;133&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;134&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;135&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; __get__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; model_instance&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; class_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;136&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; model_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FF5874;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;137&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;138&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;139&lt;&#x2F;span&gt;&lt;span&gt;        cur&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.magic_prop.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;__get__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;model_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; class_instance&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;140&lt;&#x2F;span&gt;&lt;span&gt;        cur&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; cur.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;utf-8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)		&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;141&lt;&#x2F;span&gt;&lt;span&gt;        last&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;get_cache_val&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;model_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; class_instance&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;142&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; last&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span&gt; hashlib.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;sha1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;cur&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;hexdigest&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;143&lt;&#x2F;span&gt;&lt;span&gt;            logging.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;info&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;Cache hit: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;%s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; (cur)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;144&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; getattr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;model_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;attr_name&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FF5874;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;145&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;146&lt;&#x2F;span&gt;&lt;span&gt;        logging.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;info&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;Cache miss: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;%s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; %&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; (cur)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;147&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;148&lt;&#x2F;span&gt;&lt;span&gt;        magic_done&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; = u&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;149&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.magic_pass:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;150&lt;&#x2F;span&gt;&lt;span&gt;            magic_done&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;magic_func&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;model_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; cur&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;151&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;152&lt;&#x2F;span&gt;&lt;span&gt;            magic_done&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;magic_func&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;cur&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;153&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;154&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;        # Set the attribute in the model&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;155&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;        setattr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;model_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;attr_name&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; magic_done&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;156&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;set_cache_val&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;model_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; cur&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;157&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;158&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; magic_done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;159&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;160&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;161&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; __set__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; model_instance&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;162&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; _MagicDatastore&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;163&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;            setattr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;model_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;attr_name&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; value.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;retval&lt;&#x2F;span&gt;&lt;span&gt;())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;164&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;165&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;            raise&lt;&#x2F;span&gt;&lt;span&gt; db.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;DerivedPropertyError&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;MagicProperty is magic. Magic may not be modified.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;166&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;167&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; make_value_from_datastore&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #4B6479;&quot;&gt;168&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt; _MagicDatastore&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;value&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Auto-updating Properties in Google AppEngine Models</title>
        <published>2010-02-21T04:03:42+00:00</published>
        <updated>2010-03-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Delta Regeer
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://funcptr.net/2010/auto-updating-properties-in-google-appengine-models/"/>
        <id>https://funcptr.net/2010/auto-updating-properties-in-google-appengine-models/</id>
        
        <content type="html" xml:base="https://funcptr.net/2010/auto-updating-properties-in-google-appengine-models/">&lt;p&gt;EDIT: I have an updated version of this code available in a newer post, please
go to &lt;a href=&quot;&#x2F;2010&#x2F;magic-properties-on-google-appengine&#x2F;&quot;&gt;Magic Properties on Google AppEngine&lt;&#x2F;a&gt; for the updated information.
For the generic information that has not changed, and the idea behind the code
please continue below.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;In Google AppEngine a model may contain many different properties, from this
model you can generate a form using djangoforms. This is all good and well
until you have a required property on a model that needs to have part of it be
calculated based upon something the user types in. For example, a blog entry
generally has a &quot;slug&quot; which is generated from the title, now in Google
AppEngine&#x27;s models, if a property is required it has to be set at object
creation time.&lt;&#x2F;p&gt;
&lt;p&gt;Djangoforms has a &lt;code&gt;form.save(committed=False)&lt;&#x2F;code&gt; that allows one to get back an
unsaved &lt;code&gt;Model&lt;&#x2F;code&gt;, however since slug is not in the form (since it is auto
generated) it cannot be set at model creation time. Even adding a hidden field
to the form with the name of the property is not going to satisfy the model
since a value of &lt;code&gt;None&lt;&#x2F;code&gt; is considered to be empty, which means it does not meet
the &lt;code&gt;required=True&lt;&#x2F;code&gt; status.&lt;&#x2F;p&gt;
&lt;p&gt;After trying a multitude of different options I ran across an &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;appengine&#x2F;articles&#x2F;extending_models.html&quot;&gt;article about
extending models&lt;&#x2F;a&gt; that specifically talked about adding custom properties
that were saved into the DB, and could be searched on, this got me digging and
I found &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;googleappengine.blogspot.com&#x2F;2009&#x2F;07&#x2F;writing-custom-property-classes.html&quot;&gt;a blog post on the Google AppEngine blogspot&lt;&#x2F;a&gt; about the exact same
thing, using yet again a different example. The one that got me on the right
track was the following post by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20090517114229&#x2F;http:&#x2F;&#x2F;appengine-cookbook.appspot.com&#x2F;recipe&#x2F;custom-model-properties-are-cute&#x2F;&quot;&gt;Rodrigo Moraes on his custom model
properties&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I came up with the following fairly quickly after also taking a look at
&lt;code&gt;googleappengine.ext.db&lt;&#x2F;code&gt; within the Google AppEngine framework, however there is
still an issue, for now the &lt;code&gt;MagicProperty&lt;&#x2F;code&gt; is only updated the first time the
property it affects is set. I am not yet sure how to work around that, I will
have to do some more digging, maybe there is a way to get notified if another
property gets modified or updated.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; logging&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; google.appengine.ext&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; db&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; MagicProperty&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;prop&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; magic_func=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FF5874;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; *args&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; **kw&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; magic_func:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;        # No pants required.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt; _MagicProperty&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;prop&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; magic_func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; **&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;kw&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;    else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;        # We are putting some pants on the function.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;        def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; pants&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;magic_func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt; _MagicProperty&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;prop&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; magic_func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; **&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;kw&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; pants&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFCB8B;&quot;&gt; _MagicProperty&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;db&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;Property&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;MagicProperty which will modify output based on a function that it is given.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    Inspired by: &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    http:&#x2F;&#x2F;appengine-cookbook.appspot.com&#x2F;recipe&#x2F;custom-model-properties-are-cute&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    http:&#x2F;&#x2F;code.google.com&#x2F;appengine&#x2F;articles&#x2F;extending_models.html&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    http:&#x2F;&#x2F;googleappengine.blogspot.com&#x2F;2009&#x2F;07&#x2F;writing-custom-property-classes.html&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; prop&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; magic_func&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; *args&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; **kw&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;        super&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;_MagicProperty&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;__init__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; **&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;kw&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.magic_func&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; magic_func&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span&gt;.magic_prop&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; prop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;font-style: italic;&quot;&gt; attr_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;        # In google.appengine.ex.db there is an explicit warning not to use this method, so we test for it first.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;._attr_name:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;_attr_name&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; __get__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; model_instance&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; class_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; model_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FF5874;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; TODO&lt;&#x2F;span&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;: If the property that this one is functioning on is changed, we need a way to know that so that we recalculate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;        # Original __get__ in google.appengine.ext.db has getattr to retrieve the value from the model instance&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        magic_done&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; getattr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;model_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;attr_name&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FF5874;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; magic_done&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; is&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FF5874;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            magic_done&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;magic_func&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;.magic_prop.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;__get__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;model_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; class_instance&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;            # Set the attribute in the model&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;            setattr&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;model_instance&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8EACE3;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;_attr_name&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; magic_done&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; magic_done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt; __set__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FDBCA;&quot;&gt; *args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span&gt; db.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;DerivedPropertyError&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;MagicProperty is magic. Magic may not be modified.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The approach that the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20100208035715&#x2F;http:&#x2F;&#x2F;code.google.com&#x2F;appengine&#x2F;docs&#x2F;python&#x2F;datastore&#x2F;typesandpropertyclasses.html#DateTimeProperty&quot;&gt;DateTimeProperty&lt;&#x2F;a&gt; takes is one that I can&#x27;t use
because my class is dependant upon an external property, not whether or not a
value was set when the object was instantiated.&lt;&#x2F;p&gt;
&lt;p&gt;Google AppEngine is posing some rather interesting challenges. Although, for
slugs it may not be entirely bad that it can only be set once, as that means
title changes on the article won&#x27;t cause the slug to change possibly breaking
old links. This definitely requires more research and more thinking.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Property class on AppEngine does not support a tuple for choices</title>
        <published>2010-02-15T04:56:59+00:00</published>
        <updated>2010-02-15T04:56:59+00:00</updated>
        
        <author>
          <name>
            
              Delta Regeer
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://funcptr.net/2010/property-class-on-google-appengine-not-supporting-a-tuple-of-choices/"/>
        <id>https://funcptr.net/2010/property-class-on-google-appengine-not-supporting-a-tuple-of-choices/</id>
        
        <content type="html" xml:base="https://funcptr.net/2010/property-class-on-google-appengine-not-supporting-a-tuple-of-choices/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;appengine&#x2F;&quot;&gt;Google AppEngine&lt;&#x2F;a&gt; does not allow one to set the choices field of a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20100212221437&#x2F;http:&#x2F;&#x2F;code.google.com&#x2F;appengine&#x2F;docs&#x2F;python&#x2F;datastore&#x2F;propertyclass.html#Property&quot;&gt;model
property&lt;&#x2F;a&gt;&lt;&#x2F;a&gt; to a tuple; this workaround will have have a form give the
user the choices with the user friendly items but have the backend store the
non-user friendly version.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D6DEEB; background-color: #011627;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;# Set up our non-user friendly and user friendly choices&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;REDIRECT_CHOICES&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;301&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;301 - Permanent Redirect&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;302&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;302 - Temporary Redirect&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;403&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;403 - Access Denied&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;404&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;404 - File Not Found&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;500&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;500 - Internal Server Error&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;# Sample model that has the required Property with the choices set to the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;# non-user friendly values&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFCB8B;&quot;&gt; Shorturl&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;db&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;Model&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    uripath&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; db.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;StringProperty&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt;verbose_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;Path&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt; required&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FF5874;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    httpcode&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; db.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;IntegerProperty&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt;        verbose_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;HTTP code&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt;        required&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FF5874;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt;        default&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;301&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt;        choices&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F78C6C;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt; for&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;font-style: italic;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt; REDIRECT_CHOICES&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    location&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; db.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;StringProperty&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt;verbose_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;Location&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;# This is our djangoform that has the choices set as required so that the user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #637777;font-style: italic;&quot;&gt;# gets the user friendly version and not just simply the numbers.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFCB8B;&quot;&gt; ShorturlForm&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;djangoforms&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C5E478;&quot;&gt;ModelForm&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    httpcode&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; forms.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;IntegerField&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt;        widget&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;forms.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #B2CCD6;&quot;&gt;Select&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt;choices&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #82AAFF;&quot;&gt;REDIRECT_CHOICES&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt;        required&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FF5874;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D7DBE0;&quot;&gt;        label&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #ECC48D;&quot;&gt;HTTP code&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D9F5DD;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt;    class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FFCB8B;&quot;&gt; Meta&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        model&lt;&#x2F;span&gt;&lt;span style=&quot;color: #C792EA;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; Shorturl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Given the above tuple it will set the choices in the model for Google AppEngine
and pass it to the field on the Django form allowing user friendly output. This
will allow the user to pick the right redirect choice without having to know
that various different redirect codes or have to look them up.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
