How to implement _repr_pretty in a Python mixin? - ipython

Following this discussion, I tried to include _repr_pretty in a mixin.
Without the mixin, it works as expected:
>>> class MyClass():
... def __repr__(self):
... return "The Repr."
... def __str__(self):
... return "The str."
... def _repr_pretty_(self, p, cycle):
... p.text(str(self) if not cycle else '...')
>>> my_object = MyClass()
>>> my_object
The str.
But if I move the _repr_pretty into a mixin, it does not work anymore:
>>> class MyMixin:
... def _repr_pretty_(self, p, cycle):
... p.text(str(self) if not cycle else '...')
>>> class MyClass(MyMixin):
... def __repr__(self):
... return "The Repr."
... def __str__(self):
... return "The str."
>>> my_object = MyClass()
>>> my_object
The Repr.
Any ideas?

In fact it's not a bug, it's a feature... It is explained here:
https://github.com/ipython/ipython/pull/10959,
https://github.com/ipython/ipython/pull/452.
In summary, when you write your own __repr__ in a subclass, it takes precedence over a _repr_pretty_ of a parent class. The philosophy behind it is that in that kind of case, you typically want your custom __repr__ method to be used by the IPython pretty printer also.
Here is a possible workaround:
>>> class MyMixin:
>>> def _my_repr_(self):
... raise NotImplementedError
>>> def __repr__(self):
... return self._my_repr_()
>>> def _repr_pretty_(self, p, cycle):
... p.text(str(self) if not cycle else '...')
>>> class MyClass(MyMixin):
... def __init__(self):
... super().__init__()
... def _my_repr_(self):
... return "The Repr."
... def __str__(self):
... return "The str."
>>> my_object = MyClass()
>>> my_object
The str.

Related

Scala: Invokation of methods with/without () with overridable implicits

Here is a definition of method, that uses ExecutionContext implicitly, and allows client to override it. Two execution contexts are used to test it:
val defaultEc = ExecutionContext.fromExecutor(
Executors.newFixedThreadPool(5))
Names of threads look like: 'pool-1-thread-1' to 'pool-1-thread-5'
And the 2nd one from Scala:
scala.concurrent.ExecutionContext.Implicits.global
Names of threads look like: 'scala-execution-context-global-11'
Client can override default implicit via:
implicit val newEc = scala.concurrent.ExecutionContext.Implicits.global
Unfortunately it is overridable only, when a method with implicit is invoked without ():
val r = FutureClient.f("testDefault") //prints scala-execution-context-global-11
not working:
val r = FutureClient.f("testDefault")() //still prints: pool-1-thread-1
The question is WHY it works this way? Cause it makes it much more complicated for clients of API
Here is a full code to run it and play:
object FutureClient {
//thread names will be from 'pool-1-thread-1' to 'pool-1-thread-5'
val defaultEc = ExecutionContext.fromExecutor(
Executors.newFixedThreadPool(5))
def f(beans: String)
(implicit executor:ExecutionContext = defaultEc)
: Future[String] = Future {
println("thread: " + Thread.currentThread().getName)
TimeUnit.SECONDS.sleep(Random.nextInt(3))
s"$beans"
}
}
class FutureTest {
//prints thread: pool-1-thread-1
#Test def testFDefault(): Unit ={
val r = FutureClient.f("testDefault")
while (!r.isCompleted) {
TimeUnit.SECONDS.sleep(2)
}
}
//thread: scala-execution-context-global-11
#Test def testFOverridable(): Unit ={
implicit val newEc = scala.concurrent.ExecutionContext.Implicits.global
val r = FutureClient.f("testDefault")
while (!r.isCompleted) {
TimeUnit.SECONDS.sleep(2)
}
}
//prints pool-1-thread-1, but not 'scala-execution-context-global-11'
//cause the client invokes f with () at the end
#Test def testFOverridableWrong(): Unit ={
implicit val newEc = scala.concurrent.ExecutionContext.Implicits.global
val r = FutureClient.f("testDefault")()
while (!r.isCompleted) {
TimeUnit.SECONDS.sleep(2)
}
}
}
I have already discussed a couple of related topics, but they are related to API definition, so it is a new issue, not covered by those topics.
Scala Patterns To Avoid: Implicit Arguments With Default Values
f("testDefault") (or f("testDefault")(implicitly)) means that implicit argument is taken from implicit context.
f("testDefault")(newEc) means that you specify implicit argument explicitly. If you write f("testDefault")() this means that you specify implicit argument explicitly but since the value isn't provided it should be taken from default value.

Scala - Global variable get the value in a function

I am a beginner of Scala.
I immediately get a problem.
Let's say:
I have a Vector variable and 2 functions. The first one function is calling 2nd function. And there is a variable in 2nd function is what I need to get and then append it to Vector. (Without returning the variable in 2nd function.)
The structure looks like this:
def main(args: Array[String]): Unit = {
var vectorA = Vector().empty
}
def funcA(): sometype = {
...
...
...
funcB()
}
def funcB(): sometype = {
var error = 87
}
How can I add error variable in global Vector?
I tried to write vectorA :+ error but in vain.
You could do the following:
def main(args: Array[String]): Unit = {
val vectorA = funcA(Vector.empty)
}
def funcA(vec: Vector): sometype = {
...
...
...
funcB()
}
def funcB(vec: Vector): sometype = {
// Here you could append, which returns a new copy of the Vector
val error = 87
vec :+ error
}
Keep in mind that, it is advisable to use immutable variables. Though not always this might be true, but for most of the applications that just involve doing some CRUD type logic, it is better to use immutable variables.

Object is not callable error

import math
class Word:
'''A class that represents word'''
def __init__(self, word):
self._word = word
def __str__(self):
return self._word
c = word("Hello")
print (c())
This results with "builtins.TypeError: 'Word' object is not callable"
How can I check the value of c using print(c())?

Scala's wrong forward reference error

private def foo(a:A):B = a match{
case A(...) =>
val x = a.b //error: wrong forward reference a
...
}
Where b is not mentioned in A(...), if that matters.
I've tried my luck on Google, but I seem to find only posts of people having errors involving forward references but no explanation of what this particular error actually means.
Would appreciate it if somebody could help me out.
Well, don't I feel stupid now...
private def foo(a:A):B = a match{
case A(...) =>
val x = a.b //error: wrong forward reference a
...
val a = ... //<-- THAT's the reason for the error
...
}
So a simple rename will resolve the issue:
private def foo(aa:A):B = aa match{
case A(...) =>
val x = aa.b
...
val a = ...
...
}
Here is an attempt to explain what #User1291 had not with his/her answer.
I'm new to Scala and Java so the answer wasn't obvious to me. I was surprised to run into this error in my (simplified) code:
object Main {
val data = getData()
def getUser() = {
getUserFrom(data) // error: Wrong Forward Reference
}
}
Wrong Forward Reference is equivalent to Java's Illegal Forward Reference, which is a fancy way of saying you can't reference a value that isn't known at compile time. In this case, getData() can only return value during run time, and referencing data gave this error.
When I tried changing the code to reference a known string, as expected the error went away:
object Main {
val name = "PieOhPah"
def getUser() = {
getUserFrom(name)
}
}
Another way is to close over the value with a function and access it from inside since functions are not evaluated until runtime:
object Main {
val data = getData()
def getUser(userData: UserData) = {
getUserFrom(userData)
}
// Invoke the method later with `data`
print(getUser(data).name)
}
The problem is that you are probably using pattern-matching in some wrong way. As... You have not provided complete code. I have no idea about what is that mistake.
I am sure there is a problem somewhere else as following code (which is almost same as what you have given ) works flawlessly,
scala> :pa
// Entering paste mode (ctrl-D to finish)
case class A( c: String ) {
val b: String = c
}
def demoA( a: A ): String = a match {
case A( iAmC ) => {
val x = a.b
x
}
}
// Exiting paste mode, now interpreting.
defined class A
demoA: (a: A)String
scala> val anA = A( "sdfsd" )
anA: A = A(sdfsd)
scala> demoA( anA )
res3: String = sdfsd
So... basically if you have a case class like following,
case class A( b: String, c: String )
Now following would have worked.
private def foo( a:A ): B = a match{
case A( iAmB, iAmC ) => {
// iAmB and iAmC have values of a.b and a.c repectively
...
}
}
In your case...your function clearly says that your a is an instance of A - def foo( a:A ) so... you really don't need to pattern match here.
private def foo( a:A ): B = {
// Now class A should have member b and c
val iAmB = a.b
val iAmC = a.c
...
}

Possible to conditionally elide out a subclass method?

In Scala, I'd like to have a subclass method conditionally elided out (and revert to the base class implementation) based on the command line priority. As an example, suppose I have the following code:
// File: mini.scala
import scala.annotation._, elidable._
trait FooBase {
def bar(msg: String) = println("FooBase: " + msg)
}
object Foo extends FooBase {
#elidable(INFO)
override def bar(msg: String) = println("Foo: " + msg)
}
object App {
def main(args: Array[String]) {
println("before")
Foo.bar("message")
println("after")
}
}
If I compile with:
scalac -Xelide-below MINIMUM mini.scala
And run it, I see (as expected):
before
Foo: message
after
Now if I compile with:
scalac -Xelide-below MAXIMUM mini.scala
Then, I hoped to see:
before
FooBase: message
after
But I actually see:
before
after
So instead of just the subclass method being elided out (as hoped) the base class seems to be gone too.
Any explanation appreciated.
Based on the response from #som-snytt, it seems that the best way to achieve the effect I'm after is something like:
trait DebugBase {
def on = false
}
object Debug extends DebugBase {
#elidable(INFO)
override def on = true
}
object Foo {
def bar(msg: String) = if (Debug.on) println("Foo (Debug): " + msg) else println("Foo: " + msg)
}
But then there is still a runtime check on the status of Debug.on instead of completely eliding out the debug version as you might with an #ifdef in C/C++.
That's a good one. I've looked at the mechanism once upon a time, but I wasn't sure about the use case.
The answer is commented:
/** Called if a tree's symbol is elidable. If it's a DefDef,
* replace only the body/rhs with 0/false/()/null; otherwise replace
* the whole tree with it.
*/
So in eliding Foo.bar, you don't remove the method definition. You merely turn it into def bar = () and any invocation into the unit value ().
You can elide a template method usefully:
scala> class X { def f() = { if (g() < 1) println("default") } ; def g() = 1 }
defined class X
scala> :se -Xelide-below 200
scala> class Y extends X { #elidable(100) override def g() = 2 }
defined class Y
scala> new Y().f()
default
scala> :se -Xelide-below 5
scala> class Y extends X { #elidable(100) override def g() = 2 }
defined class Y
scala> new Y().f()