- Nothing changed yet.
- Add missing
python_requires
insetup.py
to prevent installing on too old versions.
- Add support for Python 3.11.
- Drop support for Python 2.7, 3.5, 3.6.
- Fix test suite incompatibility with
zope.interface >= 6.0
.
- Title directive now correctly handles non-ascii characters.
- Fix test suite incompatibility with zope.interface >= 5.0.
- Drop support for Python 3.4.
- Add support for Python 3.9 and 3.10.
- Check for
builtins
(Python 3) everywhere that we check for__builtin__
(Python 2).
- Fix rendering of PyPI page.
- Add support for Python 3.7 and 3.8.
Add a new directive
martian.ignore()
to explicitly not grok something in a module:class Example: pass martian.ignore('Example')
Fix the code to be pep 8 compliant.
- Bypass bootstrap, add coverage to tox
- Fix
inspect.getargspec()
deprecation in python3
- Add support for Python 3.5, 3.6, PyPy2 and PyPy3.
- Drop support for Python 2.6 and 3.3.
- compatibility for python 3
- adjust egg to work with newer version of setuptools
- Fix an encoding issue under Python-2.7 in the doctests.
The computation of the default value for a directive can now be defined inside the directive class definition. Whenever there is a
get_default
classmethod, it is used for computing the default:class name(Directive): scope = CLASS store = ONCE @classmethod def get_default(cls, component, module=None, **data): return component.__name__.lower()
When binding the directive, the default-default behaviour can still be overriden by passing a
get_default
function:def another_default(component, module=None, **data): return component.__name__.lower() name.bind(get_default=another_default).get(some_component)
Making the default behaviour intrinsic to the directive, prevents having to pass the
get_default
function over and over when getting values, for example in the grokkers.
- Ignore all __main__ modules.
- List zope.testing as a test dependency.
Changes to better support various inheritance scenarios in combination with directives. Details follow.
CLASS_OR_MODULE
scope directives will be aware of inheritance of values that are defined in module-scope. Consider the following case:module a: some_directive('A') class Foo(object): pass module b: import a class Bar(a.Foo): pass
As before,
Foo
will have the valueA
configured for it.Bar
, since it inherits fromFoo
, will inherit this value.CLASS_OR_MODULE
andCLASS
scope directives will be aware of inheritance of computed default values. Consider the following case:module a: class Foo(object): pass module b: import a class Bar(a.Foo): pass def get_default(component, module, **data): if module.__name__ == 'a': return "we have a default value for module a" return martian.UNKNOWN
When we now do this:
some_directive.bind(get_default=get_default).get(b.Bar)
We will get the value "we have a default value for module a". This is because when trying to compute the default value for
Bar
we returnedmartian.UNKNOWN
to indicate the value couldn't be found yet. The system then looks at the base class and tries again, and in this case it succeeds (as the module-name isa
).martian.ONCE_IFACE
storage option to allow the creation of directives that store their value onzope.interface
interfaces. This was originally ingrokcore.view
but was of wider usefulness.
- Ignore things that look like Python modules and packages but aren't. These are sometimes created by editors, operating systems and network file systems and we don't want to confuse them.
- Ignore .pyc and .pyo files that don't have a matching .py file via
module_info_from_dotted_name
if itsignore_nonsource
parameter isTrue
. The default isTrue
. To revert to the older behavior where .pyc files were honored, passignore_nonsource=False
. - Pass along
exclude_filter
(and the newignore_nonsource
flag) to ModuleInfo constructor when it calls itself recursively. - Replace
fake_import
to import fake modules in tests with a real python import statement (from martiantest.fake import my_fake_module
). This works by introducing a metaclass forFakeModule
that automatically registers it as a module. The irony does not escape us. This also means thatmartian.scan.resolve()
will now work on fake modules.
- Added MULTIPLE_NOBASE option for directive store. This is like MULTIPLE but doesn't inherit information from the base class.
- Add a
validateClass
validate function for directives. - Moved
FakeModule
andfake_import
into amartian.testing
module so that they can be reused by external packages. - Introduce new tutorial text as README.txt. The text previously in
README.txt
was rather too detailed for a tutorial, so has been moved intocore.txt
. - Introduce a
GrokkerRegistry
class that is aModuleGrokker
with aMetaMultiGrokker
in it. This is the convenient thing to instantiate to start working with Grok and is demonstrated in the tutorial. - Introduced three new martian-specific directives:
martian.component
,martian.directive
andmartian.priority
. These replace thecomponent_class
,directives
andpriority
class-level attributes. This way Grokkers look the same as what they grok. This breaks backwards compatibility again, but it's an easy replace operation. Note thatmartian.directive
takes the directive itself as an argument, and then optionally the same arguments as thebind
method of directives (name
,default
andget_default
). It may be used multiple times. Note thatmartian.baseclass
was already a Martian-specific directive and this has been unchanged. - For symmetry, add an
execute
method toInstanceGrokker
.
- Added a
MethodGrokker
base class for grokkers that want to grok methods of a class rather than the whole class itself. It works quite similar to theClassGrokker
regarding directive definition, except that directives evaluated not only on class (and possibly module) level but also for each method. That way, directives can also be applied to methods (as decorators) in case they support it.
- Refactored the
martian.Directive
base class yet again to allow more declarative (rather than imperative) usage in grokkers. Directives themselves no longer have aget()
method nor a default value factory (get_default()
). Instead you will have to "bind" the directive first which is typically done in a grokker. - Extended the
ClassGrokker
baseclass with a standardgrok()
method that allows you to simply declare a set of directives that are used on the grokked classes. Then you just have to implement anexecute()
method that will receive the data from those directives as keyword arguments. This simplifies the implementation of class grokkers a lot.
scan_for_classes
just needs a single second argument specifying an interface. The support for scanning for subclasses directly has been removed as it became unnecessary (due to changes in grokcore.component).
- Replaced the various directive base classes with a single
martian.Directive
base class:- The directive scope is now defined with the
scope
class attribute using one ofmartian.CLASS
,martian.MODULE
,martian.CLASS_OR_MODULE
. - The type of storage is defined with the
store
class attribute using one ofmartian.ONCE
,martian.MULTIPLE
,martian.DICT
. - Directives have now gained the ability to read the value that they
have set on a component or module using a
get()
method. Theclass_annotation
andclass_annotation_list
helpers have been removed as a consequence.
- The directive scope is now defined with the
- Moved the
baseclass()
directive from Grok to Martian. - Added a
martian.util.check_provides_one
helper, in analogy tocheck_implements_one
. - The
scan_for_classes
helper now also accepts aninterface
argument which allows you to scan for classes based on interface rather than base classes.
- added dummy
package_dotted_name
toBuiltinModuleInfo
. This allows the grokking of views in test code using Grok'sgrok.testing.grok_component
without a failure when it sets up thestatic
attribute. - no longer use the convention that classes ending in -Base will be considered base classes. You must now explicitly use the grok.baseclass() directive.
- The type check of classes uses isinstance() instead of type(). This means Grok can work with Zope 2 ExtensionClasses and metaclass programming.
- Added an OptionalValueDirective which allows the construction of
directives that take either zero or one argument. If no arguments
are given, the
default_value
method on the directive is called. Subclasses need to override this to return the default value to use.
- Move some util functions that were really grok-specific out of Martian back into Grok.
- scan.module_info_from_dotted_name() now has special behavior when it runs into __builtin__. Previously, it would crash with an error. Now it will return an instance of BuiltinModuleInfo. This is a very simple implementation which provides just enough information to make client code work. Typically this client code is test-related so that the module context will be __builtin__.
- Grokkers now receive a
module_info
keyword argument. This change is completely backwards-compatible since grokkers which don't takemodule_info
explicitly will absorb the extra argument in**kw
.
- Reverted the behaviour where modules called tests or ftests were skipped by default and added an API to provides a filtering function for skipping modules to be grokked.
- Don't grok tests or ftests modules.
- Fix a bug where if a class had multiple base classes, this could end up in the resultant list multiple times.
- Initial public release.