On 7/6/14, 6:16 AM, Kim Gräsman wrote:
Hi all,
I've done most of the mechanical changes for Python 3 compatiblity in pymake.
But now I've come to the module structure. There are some challenges.
In Python 3, imports first check the standard library and then fall
back to searching the current directory [0]. Pymake's parser module
happens to conflict with the standard library parser module [1]. There
are essentially two solutions to this problem:
1) Rename parser.py -> mkparser.py and pray that we don't conflict again
2) Qualify imports always, e.g. ``import pymake.parser`` or ``from
pymake import parser``
(2) seems superior to me, as it paves the way for packaging. Once
pymake is installed in site-packages, using qualified imports is the
most natural way to reference modules, and development is easier
because we can just set PYTHONPATH to the checkout path, and imports
work transparently as if pymake was installed.
So I started moving toward this model, but immediately got stuck
because qualified imports do not allow circular module dependencies. I
generated a dependency graph for Pymake, and it came out like this:
http://tinypic.com/r/if3c40/8
To focus on the problem I trimmed everything that wasn't involved in a
cycle, so I could see more clearly which modules had circular deps:
http://tinypic.com/r/fa8uix/8
I have some ideas for dependency breaking, but some deps are so deeply
ingrained that I need some hand-holding...
I anticipated this would be a difficult problem to solve.
I would suggest two phases.
First, get the naming sorted out. Ensure all modules are using relative
imports (from . import data) or are using fully qualified imports (from
pymake import data).
Second, break the import cycles. If modules only have 1 or 2 references
to another module that's in a cycle, move the module-level import into a
def. As a follow-up, you can move things around to break the cycle. If
you really want to be hacky, you can have the "parent" module set
attributes on the "child" module for the symbols needed by the child. e.g.
# parent.py
from . import child
def parent_fn():
pass
child.parent_fn = parent_fn
# child.py
def foo():
parent_fn()
This breaks "import pymake.child" unless "parent" has been imported. But
it breaks the cycle.
Long term, we should refactor to avoid this hackery. But as someone who
has attempted that once, it's not going to be fun. I encourage you to
try. But don't dismiss a "good enough" hacky solution.
_______________________________________________
dev-builds mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-builds