dag / braindump Goto Github PK
View Code? Open in Web Editor NEWIdeas and Experiments
Ideas and Experiments
Could maybe be transparent if the adapter issubclass the requested interface and the constructor has a type annotation:
@adapter # venusian
class UserPerson(PersonInterface):
def __init__(self, user:UserInterface):
self.user = user
@property
def first_name(self):
return self.user.given_name
@property
def last_name(self):
return self.user.family_name
def greet(self, person):
return '{greeting}, {person.first_name}'.format(
greeting=self.user.catch_phrase, person=person)
adapt = AdapterRegistry()
adapt.scan() # find @adapter
adapt(user_object, PersonInterface) # UserPerson(user_object)
Probably a complete ripoff of existing options such as the ZCA. I should blame moraes for bugging me about it. :)
# an instance of a jinja environment has been created and registered
@created(jinja2.Environment)
def configure_line_statements(env): # pass the instance as the first argument
env.line_statement_prefix = '#'
# a request has started
# find all utilities in the registry matching the annotated types in the function signature
# call the function once for each combination of the found utilities
@started(RequestEvent)
def log_request(log: logbook.Logger, request: werkzeug.BaseRequest):
log.info('{request.method} {request.path}', request=request)
Embed constraints in code, that can be disabled in production for performance and fault-tolerance, but helpful in development / automated testing. Python supports this via the assert statement, which is stripped out if Python runs with optimizations (__debug__
is false), but assertions are rather low-level. A support package could provide tools for adding type constraints, design-by-contract etc, in a more high-level fashion than simple assertions. Python also strips out branches for code like if __debug__
when optimized which could allow constraints added via for example decorators to only have a slight overhead at "construction time", that is, usually only once on the first import.
Contracts with magical abuse of frames:
def double(x):
return x * 2
@pre
def double(x):
assert isinstance(x, numbers.Number)
@post
def double(r, x):
assert isinstance(r, numbers.Number)
assert r > x
Or using decorator arguments:
@accepts(x=numbers.Number)
@returns(numbers.Number, x=operator.gt)
def double(x):
return x * 2
Annotations:
@constrained
def double(x: numbers.Number) -> numbers.Number, dict(x=operator.gt):
return x * 2
Constrained attributes using descriptors:
class Person(object):
name = Attribute(basestring)
When running with optimizations it could simply return None
.
Like with #1, some of these exist in my experimental Attest rewrite, and similarly this idea is a result of it.
__call__
import
, a reserved keyword, becomes import_
(the standard convention) and string with spaces-and-hyphens
becomes string_with_spaces_and_hyphens
and so on. This is useful for example when mapping command-line arguments to functions and attributes in Python, such that while --not --master-of-the-universe=me
might map to while_(not_=True, master_of_the_universe='me')
. It should also be reversible, with a parameter for the underscore substitute.
@test
and @test.using(parameters)
rather than requiring the first to be @test()
or ambiguously checking if the arguments are a single callableCaution: Asperger humor ahead!
Related to #5, #6 and #7, but only focusing on interfaces.
The longer ones become an annoyance once you start putting them in function annotations in particular. You want the signature to be short and concise, preferably fitting on one line. Also repeating "Interface" or such for every type quickly starts to sound like a broken record.
The stdlib doesn't seem completely self-consistent anyway:
The general trend though seems to be a preference recently for plain nouns with mixed abstract/concrete methods.
class PersonType (metaclass=Interface):
# typed attribute
first_name = str
# untyped attribute using the Ellipsis constant
last_name = ...
# special method for asserting invariants about the object
def __invariant__(self):
assert self.first_name or self.last_name, 'must set at least one of the names'
# abstract methods with type annotations
def greet(self, person: PersonType) -> str:
# normally "PersonType" isn't available yet when the "def" executes;
# a workaround could be to have a special "This" type á la Traits,
# although it could be aliased to the class name using __prepare__ in the metaclass
# contractual pre-condition assertions in the abstract method body
assert person is not self, 'not greeting myself, silly'
# generator coroutines for contractual post-conditions
res = yield
assert len(res) < 100, 'i am not a blabbermouth dammit'
# implementations simply inherit from the interface.
# if the implementation is complete, issubclass will be true for the interface,
# if not, instance creation will fail
class Person (PersonType):
...
If a class conforms to an interface but does not inherit from it, issubclass should be false but there could be a custom API for checking conformance beyond inheritance. Perhaps calling an interface with an object could return the object if it is conforming, and otherwise raise an error, forming a simplistic adapter.
Not sure if useful, but here goes:
AST/Import hook for transforming assertions to substitute for alternative behavior.
Though argparse is an improvement over optparse, it still feels more like a low-level toolkit for building more high-level systems. ConfigParser doesn't handle deep nesting and isn't type-aware, in itself.
Many of these ideas come from, and are partially implemented in, my unpublished experimental rewrite of Attest, and the idea itself of a CLI framework is a result of it, after noticing a pattern and experiencing some annoyances.
--help
etc)Maybe not a useful idea as good implementations might already exist, but this is called a braindump for a reason.
Existing options include zope.interface, enthought's traits, schema libraries like flatland and colander, less generic libraries for dealing with html forms, and all sorts of implementations of database-mapped "model" objects. So maybe this idea is useless :) though I'm pondering the usefulness of unifying all these different use cases.
git shortlog -nse
(Ideally, Git and Github above should read as "arbitrary version control system" and "arbitrary source code host".)
Something like:
@somedecorator('argument', keyword='also')
def func():
pass
registry = Registry()
registry.scan(__name__, param='something')
>>> registry['somedecorator']
[Record(object=<function func at ...>,
args=('argument',),
kwargs={'keyword': 'also', 'default': 'overridable'},
params={'param': 'something'})]
Decorators could be created using a @recorder
decorator on functions that return the registry key (falling back on the function name):
@recorder
def somedecorator(arg, keyword, default='overridable'):
"""Register a "some"."""
lxml suggests this beast for portably importing the "best" available elementtree:
try:
from lxml import etree
print("running with lxml.etree")
except ImportError:
try:
# Python 2.5
import xml.etree.cElementTree as etree
print("running with cElementTree on Python 2.5+")
except ImportError:
try:
# Python 2.5
import xml.etree.ElementTree as etree
print("running with ElementTree on Python 2.5+")
except ImportError:
try:
# normal cElementTree install
import cElementTree as etree
print("running with cElementTree")
except ImportError:
try:
# normal ElementTree install
import elementtree.ElementTree as etree
print("running with ElementTree")
except ImportError:
print("Failed to import ElementTree from any known place")
Flask includes this code to get a simplejson module:
json_available = True
json = None
try:
import simplejson as json
except ImportError:
try:
import json
except ImportError:
try:
# Google Appengine offers simplejson via django
from django.utils import simplejson as json
except ImportError:
json_available = False
And this for blinker:
signals_available = False
try:
from blinker import Namespace
signals_available = True
except ImportError:
class Namespace(object):
def signal(self, name, doc=None):
return _FakeSignal(name, doc)
class _FakeSignal(object):
"""If blinker is unavailable, create a fake class with the same
interface that allows sending of signals but will fail with an
error on anything else. Instead of doing anything on send, it
will just ignore the arguments and do nothing instead.
"""
def __init__(self, name, doc=None):
self.name = name
self.__doc__ = doc
def _fail(self, *args, **kwargs):
raise RuntimeError('signalling support is unavailable '
'because the blinker library is '
'not installed.')
send = lambda *a, **kw: None
connect = disconnect = has_receivers_for = receivers_for = \
temporarily_connected_to = connected_to = _fail
del _fail
Logbook proposes this for stubbing a fake when not installed:
try:
from logbook import Logger
except ImportError:
class Logger(object):
def __init__(self, name, level=0):
self.name = name
self.level = level
debug = info = warn = warning = notice = error = exception = \
critical = log = lambda *a, **kw: None
Patterns like these could be located and put in a single, bundle-friendly module, with apipkg-like magic for lazy importing.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.