Surprising behaviour using TemplateEngine with variable "URL" interpreted as class - templates

Given the following Groovy code:
def engine = new SimpleTemplateEngine()
def propMap = [ URL: "http://stackoverflow.com",URL2: "http://stackoverflow.com"]
def result = engine.createTemplate('''
${URL}
${URL2}
''').make(propMap) as String
println(java.net.URL)
the output is
class java.net.URL
http://stackoverflow.com
Somehow the URL ends up being interpreted as class java.net.URL (which Groovy seems to be auto-importing), but why? And can a variable named URL used in this context?

Groovy is making several default imports, which also includes java.net. Import java.net.URL apparently shadows your local variable.
You could use this to explicitly tell Groovy to use your variable instead of java.net.URL.
${this.URL}
${URL2}
I also tried to use alias for import like this:
import java.net.URL as JavaURL
but it didn't really help, because both implicit (URL) and explicit (JavaURL) imports were used.

Related

Object has no attribute '__bases__' when calling inspect.getmro()

I have a python class that inherits from storm.py from the Apache Storm MultiLang project.
My class looks like the following:
import storm
class MyClassName(Storm.Bolt):
def initialize(self,conf,context):
self._conf = conf;
self._context = context
def process(self, in_tuple):
storm.ack(in_tuple)
if __name__ == '__main__':
MyClassName().run()
I copied my python file (myfilename.py) out to /usr/lib64/python2.7/site-package. I then logged into the python shell and did an import myfilename. That completed without error. When I run the following inspect.getmro(myfilename.MyClassName()) I get the following error:
AttributeError: 'MyClassName' object has no attribute '__bases__'
I was under the impression that when I declared my class and passed it Storm.Bolt that I was extending Storm.Bolt. My questions are:
Do I need to define __bases__ in my class?
What else am I missing?
Using Python 2.7.13 on CentOs7. Storm version is 1.1.0
The inspect.getmro function expects its argument to be a class, but you're passing it an instance. Get rid of the parentheses that call the class and your code should work:
inspect.getmro(myfilename.MyClassName) # not MyClassName()!
If the call you gave in the question was a simplified example and you don't have the class directly available where you're calling getmro on the instance, you can use type to get the class:
obj = SomeClass() # this happens somewhere earlier on, and we don't know SomeClass below
inspect.getmro(type(obj)) # but we can easily get it using type()

Python. Hint for variable

I'm using PyCharm as editor. For example, I have next function:
def get_instance():
# method without doc sctring in some module
# returns instance of MyClass
return some_var
And I have second file which calls get_instance():
var = get_instance()
How I can to define type of data for value? I want to use autocomplete for variable.
For example in php it will be like this:
/** #var MyClass $var */
$var = getInstance();
After this I will be see all methods and properties of $var. How to declare docstring for python variable? I know about :type and :rtype, but if I need declare type for specific variable? Can I declare a few types? What I should do?
Note: I can't do any changes with get_instance().
I don't think you can do this via docstring, but there is a mechanism called annotation. You can append whatever expression you want to parameters following a colon : and to the function declaration itself using an arrow ->. For example:
def getInstance(param: str) -> MyClass
return some_var
I have added an input parameter for purposes of illustration here. In this case str and MyClass are objects that represent the expected input and return types, respectively. They are never used in your code directly, just stashed away in an func_annotations attribute for end users that care about that sort of things (like editors).
You can do it in the same way as description properties of class. Here example:
from example_module import MyClass
var = get_instance()
"""
:type var: MyClass
"""
Also you can use description without import like this:
var = get_instance()
"""
:type var: example_module.MyClass
"""
The second way is using PEP 484:
test = my() # type: dict
Examples of autocomplete in Pycharm:

Selenium Webdriver Python page object MainPageLocators class why does it use an asterisk infront of the class name

I have been following the page object model for my Selenium Webdriver tests in Python. I have followed the sample from GitHub.
URL is: https://github.com/baijum/selenium-python/blob/master/source/page-objects.rst
When you call the locator from the MainPageLocators class e.g from the URL.
element = self.driver.find_element(*MainPageLocators.GO_BUTTON)
It uses an asterisk in front of the class name *MainPageLocators.
Why does it use * ?
It does not work if you use MainPageLocators, you have to use *MainPageLocators.
This is no good because when i use the WebDriverWait it does not work with *MainPageLocators or MainPageLocators.
E.g.
element = WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((*MainPageLocators.locator)))
I have to to do it this way for it to work which defeats the purpose of having the locators in one place.
element = WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.ID, 'button_id')))
Why the asterisk in front of MainPageLocators?
Why does *MainPageLocators not work inside the WebDriverWait?
It does work if you do
self.driver.find_element(*MainPageLocators.locator)
But it does not work if you use it in the WebDriverWait
Thanks,
Riaz
In this context, * is the argument-unpacking operator. It tells Python to unpack the values in the sequence that follows and pass them as arguments to the function. For example,
foo(*(1, 2, 3))
is equivalent to
foo(1, 2, 3)
Since MainPageLocators.GO_BUTTON is defined like this:
class MainPageLocators(object):
"""A class for main page locators. All main page locators should come here"""
GO_BUTTON = (By.ID, 'submit')
it follows that find_element(*MainPageLocators.GO_BUTTON) is equivalent to
find_element(By.ID, 'submit')
This works since find_element expects 2 arguments.
In contrast, EC.element_to_be_clickable expects a single 2-tuple as its argument. Therefore you would not want to use the argument-unpacking operator here. Instead, just pass the 2-tuple directly:
wait = WebDriverWait(self.driver, 20)
element = wait.until(EC.element_to_be_clickable((By.ID, 'submit'))
or use
element = wait.until(EC.element_to_be_clickable(MainPageLocators.GO_BUTTON)

Django URLs: How to handle a parameter

In my url.py i have the following line:
url(r'^mypage/(?P<q_id>\d+)/$', QuizWizard.as_view(generate_form_tuples()), name='nickname'),
QuizWizard is a SessionWizardView
generate_form_tuples is a function (defined inside this module, which has an optional parameter):
def generate_form_tuples(q_id=1):
...
So, when you get on mypage/ you will (maby) have a q_id.
How can i get this parameter from the url and pass it to the generate_form_tuples() function ?
P.S. I know that if I redirect this to be handled in a view, the parameter will be sent automatically having as name : q_id
One way is to redesign it a bit, like this:
url(r'^mypage/(?P<q_id>\d+)/$', generate_form_tuples, name='nickname'),
...
def generate_form_tuples(request, q_id=1):
...
return QuizWizard.as_view(...)(request, q_id=q_id)

django import a view function

I have a django application xxx which does a number of things.
I also have a sepaerate application yyy. Which wants to call one of the functions of xxx.
Is there a way for me to import the functions?
For example, in yyy can i say
from toplevel.xxx import doit
Or what is the best approach, I dont want to duplicate code.
Of course, you can fo it.
With a proper import and parameter, you can do it.
#app: app1
#someview.py
def a_view(request, someparam):
#some code here
#app: app2
#otherview.py
from app1.someview import a_view
def another_view(request):
param = 1
a_view(request, param)
As for an example
UPDATE: Wish to mention that, your function a_view() do not have to get a parameter at all. So you can call functions with no paramaters. I just wish to mention that, if your function have paramaters, you have to pass them as if you do within an application.