What happens if you type from and then hit the Tab key? The autocompleter should suggest all the modules you can import, including the navigation module, with the correct number of dots!
Thanks @meredydd and @alcampopiano. This is what I have got (I am following along with the great tutorial from TalkPython.fm to kickstart me back into Anvil).
Hmm, I’m not sure. Can you share a clone to demonstrate? Or perhaps show a bit more code. I might be missing something but the error seems to reach a navigation module or form. When I misspell my module name just to see the error, the traceback just involves the main and sub form.
Since your sub form “AddMeasurementComponent” does not reference anything in the navigation module, perhaps it is best to only import the navigation module in the main form (since that it where navigation is used). Everything seems to work when I do this. Does this help get you passed the issue?
I will be using the navigation Module to move to the Homeform afterwards using the go_home() in the navigation module. Inside of the AddMeasurementComponent. Is it not possible to import the navigation module inside the AddMeasurementComponent ?
If you want to be redirected to home after the user clicks “add measurement” you could do:
def button_save_click(self, **event_args):
.
.
.
# this gives you a reference to the main form
get_open_form().link_home_click()
I have not been able to import navigation inside your subform based on your setup for some reason (there might be an issue with circular imports, or a bug) but you should have access to its various functions via your main form.
If I had to guess I’d say that when the sub form imports navigation, it happens to be before the main form has actually finished importing it, hence the error that navigation does not exist.
I can confirm that, as @alcampopiano suspected, the issue is a circular import, which Python doesn’t like! You’re importing AddMeasurementComponent from navigation, and you’re importing navigation from AddMeasurementComponent.
One way to solve this problem is to import the navigation module from inside the button-click function, eg:
def button_save_click(self, **event_args):
from .. import navigation
# ...
Thank you @meredydd & @alcampopiano strange that it seems to work on the TalkPython.fm oh well looks like I will have to use that instead thank you for your help
I haven’t seen the code from that course but I believe that circular imports are probably best to avoid from a design perspective. So, I would go with Meredydd’s solution (I’ll mark it as correct).
I agree on the circular imports. In practice, however, software often grows “organically” (incrementally). New requirements are found (or created), resulting in new functions.
Then the question arises, where do I put new function X so that it avoids circularity? In a sufficiently large code base, even detecting circularity is a problem. Thus far, I have not found any design tools (that work under Windows) for addressing this problem. Are there any?
Please take this feedback the right way. I am not being critical. Sorry, if it comes over like a rant!
I opened https://github.com/talkpython/anvil-course/issues/2 because the TalkPython team need to be involved with this issue. I would guess that from your perspective it is a perfectly reasonable & valid suggestion to consider refactoring the navigation via the button. However, from a beginners perspective your proposal isn’t really a solution in the context of a beginners introductory code-along tutorial purporting to show how easy it is to develop on anvil.works. It might be asking a bit much of a beginner perhaps? The beginner would have to refactor a proper developers project from that point forwards. It’s quite a lot of work and it’s probably unrealistic.
You have a relationship with TalkPython that might need a bit of maintenance. That tutorial of their’s is not a good advertisement for anvil.works. Even if it’s not your code that’s the problem, have you considered liaising with the authors? I’m the third commentator who has been derailed by it. I wonder if the other two just gave up and moved on like I’m intending to?
Actually, I’ll probably try a few of your official tutorials and see if they work once I’ve calmed down. I’m a bit disappointed and frustrated, having got this far, to have hit a brick wall. I can see a lot of potential value in persisting with anvil.works - it ought to be just the job for someone like me! We will see…
I think maybe a couple of us on the forum can take a look at the course code and update it with anvil new style Forms packages… Then share it on the forum - maybe pin it - with a clone link to save other people frustration…
@paddy10tellys - have you made any contact with author - maybe they could also update their course with updated code to reflect the recent anvil updates…
Yup. I’ve had similar issues trying to install and use Eclipse and its ecosystem. It is very frustrating to follow instructions, verbatim, and fail. At first it seems like our own fault. Only later do we discover that the tool has far outpaced its documentation and examples.
How it gets that way is, alas, understandable. As someone who has written extensive documentation, it is very frustrating to hear higher-ups say “don’t bother working on docs or tutorials. You’re the only person on the planet who actually reads that stuff. Features are the priority. Those are things that real people will use.” (That isn’t happening to me anymore, but if it does, I’ll show them this thread.) Man-hours are always limited, and so priorities will always be in some conflict or other.
As for Python’s circular imports, I’ve been bitten quite a few times. Strictly speaking, it’s my own fault, but they are trivially easy to create, produce no warnings whatsoever, and most of the time, they just work anyway. The main problem is, when they don’t, there is often no immediately obvious solution.
The general guideline – which works more often in Python libraries and programs than in Python scripts – is to never use from ... import. While that gives much-superior documentation to the program – it makes usage explicit – unfortunately that syntax also makes the code much more vulnerable to circularity issues. Workaround: use plain import instead.
That doesn’t prevent circular imports in the first place, though. I’ve never heard of any algorithm that would help developers prevent them, or help refactor them once they turn problematic. (If there was, someone would probably have turned it into a tool by now.)