Skip to content

Conversation

mkoeppe
Copy link
Contributor

@mkoeppe mkoeppe commented Jan 28, 2024

sage.features is shipped by sagemath-environment, but the version file that the Feature introduced in #37024 uses is shipped by sagemath-repl.

This breaks doctesting in a modularized environment. As seen in ipython/ipython#14317 (https://github.com/ipython/ipython/actions/runs/7731330166/job/21078723213?pr=14317#step:9:136)

📝 Checklist

  • The title is concise, informative, and self-explanatory.
  • The description explains in detail what this PR is about.
  • I have linked a relevant issue or discussion.
  • I have created tests covering the changes.
  • I have updated the documentation accordingly.

⌛ Dependencies

Comment on lines 59 to 63
try:
with open(filename) as f:
return f.read().strip()
except FileNotFoundError:
return "unknown"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is overly complicated. Just kill the file and hardcode the string here. I'd even kill the whole "threejs version" business which is completely nuts and anti-modular. (Could all of this be replaced by https://github.com/jupyter-widgets/pythreejs ?)

Anyway, the whole modularization business is just too complicated. What do you mean "sage.features is shipped by sagemath-environment, but the version file that the Feature uses is shipped by sagemath-repl." Certainly all the pieces needed to use threejs (including the feature, etc) should go in the same "module".

Modularization should be about reducing complexity, not increasing it. Modules should have clear separation of concerns and communicate via clear well-defined interfaces.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the whole modularization business is just too complicated.

Your sentence is not complete. When you say "too ...", you need to say "for ..." as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the whole modularization business is just too complicated.

Your sentence is not complete. When you say "too ...", you need to say "for ..." as well.

No, I don't. I think it's too complicated, period.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modularization should be about reducing complexity, not increasing it.

You have already made it sufficiently clear that you're not interested, and that's fine; but I'll explain it nevertheless for the audience.

No, modularization is not primarily or absolutely about "reducing complexity". There are other criteria such as reusability and portability and deployability. Generally we decide to break out modules from a larger unit for a combination of such reasons. In the case of the Sage modularization project (#29705), "complexity" ranks last among these 4 criteria in importance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean "sage.features is shipped by sagemath-environment, but the version file that the Feature uses is shipped by sagemath-repl."

As you can see in

the Feature definitions are provided by the small distribution sagemath-environment, which by design has no dependencies -- it is for detecting, not providing features. That's the well-defined interface, separation of concerns etc.

sagemath-environment certainly should not ship the plotting support code that we have in sage/ext_data/threejs/ -- where the threejs-version.txt file resides.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for the registry itself: at first sight it looks like the kind of thing python entry points are designed for.

Yes, I did consider this briefly when I wrote the all_features thing. But ultimately I think it's not the right tool for it.

Why not?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm generally skeptical when using a "configuration file" is brought in as a proposed solution...

The actual code to check the feature presence and how to search for the feature in the system (when applicable) can still belong to the module.

That is already possible and does not require a redesign of the whole thing. See for example: https://github.com/sagemath/sage/blob/develop/src/sage/features/mip_backends.py#L33

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that your design allows the different packages/distributions to be split at arbitrary file boundaries, the file could still be sage.features.threejs, but just shipped by a different distribution.

I thought I explained this already: If the module sage.features.threejs were shipped by a different distribution, then client code would have to already use try: ... except: when importing the feature.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought I explained this already: If the module sage.features.threejs were shipped by a different distribution, then client code would have to already use try: ... except: when importing the feature.

  1. There's no "client code" for threejs outside of sage.repl, so there's no harm shipping sage.features.threejs together with sage.repl.
  2. Even if there was client code, it could get the feature with something like get_feature("threejs"), so the try: import ... would be abstracted away.

It seems to me we are back to non-constructive mode.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the current implementation, sage.features.threejs gets the version info from a text file shipped as package data shipped by the responsible distribution. My fix just repairs this for the case that that distribution is not instsalled.

This could as well be replaced along lines similar to what you mention in https://github.com/sagemath/sage/pull/37178/files#discussion_r1470471049: try: except for importing a function that returns the version info.

Either one is fine with me. Reworking the whole of the design of sage.features does not seem interesting to me

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Jan 31, 2024

Let's merge this simple fix please.

@tornaria
Copy link
Contributor

sage.features is shipped by sagemath-environment, but the version file that the Feature introduced in #37024 uses is shipped by sagemath-repl.

This breaks doctesting in a modularized environment. As seen in ipython/ipython#14317 (https://github.com/ipython/ipython/actions/runs/7731330166/job/21078723213?pr=14317#step:9:136)

Here your problem is that sagemath-repl fails to include threejs support files.

AFAICT, threejs is a requirement for the ipython backends, as declared in their supported_output() methods.

Your problem should go away when you add the required files to sagemath-repl.

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Jan 31, 2024

To correct what I stated earlier, the plotting support code is actually intended to be shipped with sagemath-plot, not sagemath-repl. See https://github.com/mkoeppe/sage/blob/t/32432/modularization_of_sagelib__break_out_a_separate_package_sagemath_polyhedra/pkgs/sagemath-plot/MANIFEST.in.m4

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Jan 31, 2024

Here your problem is that sagemath-repl fails to include threejs support files.

No, the problem is that, contrary to the design of sage.features, one cannot test the feature sage.features.threejs.ThreeJS when only sagemath-environment is installed.

@tornaria
Copy link
Contributor

To correct what I stated earlier, the plotting support code is actually intended to be shipped with sagemath-plot, not sagemath-repl.

Sure, but it's the ipython backend that claims to support threejs. If you ship the ipython backend with sagemath-repl then you have to ship the threejs support files with sagemath-repl. Or at least, make it so that the ipython backend realizes threejs support is not available and then not claim to support it...

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Jan 31, 2024

That's exactly what would be implemented by calling Threejs().is_present(); and fixing that is what I'm doing here.

@tornaria
Copy link
Contributor

Here your problem is that sagemath-repl fails to include threejs support files.

No, the problem is that, contrary to the design of sage.features, one cannot test the feature sage.features.threejs.ThreeJS when only sagemath-environment is installed.

There is my mistake: there is no reason whatsoever that this needs to be a feature.

@tornaria
Copy link
Contributor

That's exactly what would be implemented by calling Threejs().is_present(); and fixing that is what I'm doing here.

No, it's not:

sage: from sage.features.threejs import Threejs
sage: Threejs().is_present()
FeatureTestResult('threejs', False)
sage: get_display_manager().supported_output()
frozenset({<class 'sage.repl.rich_output.output_basic.OutputAsciiArt'>,
           <class 'sage.repl.rich_output.output_basic.OutputLatex'>,
           <class 'sage.repl.rich_output.output_basic.OutputPlainText'>,
           <class 'sage.repl.rich_output.output_basic.OutputUnicodeArt'>,
           <class 'sage.repl.rich_output.output_graphics.OutputImageDvi'>,
           <class 'sage.repl.rich_output.output_graphics.OutputImageGif'>,
           <class 'sage.repl.rich_output.output_graphics.OutputImagePdf'>,
           <class 'sage.repl.rich_output.output_graphics.OutputImagePng'>,
           <class 'sage.repl.rich_output.output_graphics3d.OutputSceneJmol'>,
           <class 'sage.repl.rich_output.output_graphics3d.OutputSceneThreejs'>,
           <class 'sage.repl.rich_output.output_graphics3d.OutputSceneWavefront'>})

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Jan 31, 2024

I know that I haven't implemented what you just wished for!

When I said "fixing that is what I'm doing here", "that" is calling to Threejs().is_present(), which is broken right now.

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Jan 31, 2024

there is no reason whatsoever that this needs to be a feature.

But that feature name does appear in a # needs directive.

@tornaria
Copy link
Contributor

there is no reason whatsoever that this needs to be a feature.

But that feature name does appear in a # needs directive.

I added that. It's not necessary for tests to pass (given that threejs is "standard", not "optional").

Now, with your "fix" in this PR, the "threejs" feature will never be available when you test sagemath-repl. You just broke the feature.

The only way the feature can work is if it knows the version, so either you ship the file with sagemath-environment, or you hardcode the version in the function.

There:

--- a/src/sage/ext_data/threejs/threejs-version.txt
+++ /dev/null
@@ -1 +0,0 @@
-r122
diff --git a/src/sage/features/threejs.py b/src/sage/features/threejs.py
index 4517523918d..c6b811dd36f 100644
--- a/src/sage/features/threejs.py
+++ b/src/sage/features/threejs.py
@@ -52,12 +52,7 @@ class Threejs(StaticFile):
             sage: Threejs().required_version()
             'r...'
         """
-        from sage.env import SAGE_EXTCODE
-
-        filename = os.path.join(SAGE_EXTCODE, 'threejs', 'threejs-version.txt')
-
-        with open(filename) as f:
-            return f.read().strip()
+        return "r122"
 
 
 def all_features():

It's a sin from a modularization point of view, but it's not worse than the alternatives.

Beware: I think you'll break arch which ships a different version of threejs. But that's a design choice.

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Jan 31, 2024

Now, with your "fix" in this PR, the "threejs" feature will never be available when you test sagemath-repl.

You mean, when I test sagemath-repl in an environment where sagemath-plot is not installed.
It's fine that it says that the feature is not available. What's your concern about this answer?

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Jan 31, 2024

hardcode the version in the function. [... diff elided ]
It's a sin from a modularization point of view, but it's not worse than the alternatives.

It's obviously strictly worse than my solution.

@tornaria
Copy link
Contributor

I know that I haven't implemented what you just wished for!

I wish I wish with all my heart, to fly with dragons in a land apart.

When I said "fixing that is what I'm doing here", "that" is calling to Threejs().is_present(), which is broken right now.

No. Your distribution is broken because it's not shipping a file that is required to decide if threejs is present or not. At least as it is it errors out. Your commit introduces a silent bug where the feature will incorrectly claim threejs is not present when it is.

This is not theoretical: since some doctests in sage.repl need threejs, and you want to ship this file in sage.plot, you are effectively disabling those tests.

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Jan 31, 2024

The problem in this discussion is that we're talking about something that is insufficiently defined (per docstring of the Threejs feature, "the presence of threejs-sage in a few standard locations" -- without reference to versions or anything).
Because it is insufficiently defined, it's meaningless to declare that the behavior after the change in this PR is a "bug".
In other words, what you're writing is "not even theoretical".

@tornaria
Copy link
Contributor

tornaria commented Feb 1, 2024

--- a/src/sage/features/threejs.py
+++ b/src/sage/features/threejs.py
@@ -6,7 +6,7 @@ from . import StaticFile
 class Threejs(StaticFile):
     r"""
     A :class:`~sage.features.Feature` which describes the presence of
-    threejs-sage in a few standard locations.
+    threejs-sage version r122 in a few standard locations.
 
     EXAMPLES::
 
@@ -52,12 +52,7 @@ class Threejs(StaticFile):
             sage: Threejs().required_version()
             'r...'
         """
-        from sage.env import SAGE_EXTCODE
-
-        filename = os.path.join(SAGE_EXTCODE, 'threejs', 'threejs-version.txt')
-
-        with open(filename) as f:
-            return f.read().strip()
+        return "r122"
 
 
 def all_features():

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Feb 1, 2024

Now it's defined, but you've already explained yourself why that change is a bad idea -- this design is worse for distributions that want to ship a different version.

@tornaria
Copy link
Contributor

tornaria commented Feb 1, 2024

Now it's defined, but you've already explained yourself why that change is a bad idea -- this design is worse for distributions that want to ship a different version.

The bad design starts with having the version in the file path, effectively creating a piece of software named threejs-sage/r122. There's no way to use a different version without patching sagemath in any case.

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Feb 1, 2024

It's a bit too easy to just call it "bad design". The versioning was introduced for a specific reason: It was claimed at that time that threejs does not make any compatibility guarantees between different versions (I have no first-hand knowledge of that). In the classic (pre-Jupyterlab) Jupyter notebook, extensions such as the threejs viewer would be installed in the frontend but would have to be compatible with multiple kernels (including different Sage installations). This concern may be outdated after the switch to the Jupyterlab technologies and its "federated" extensions. (I don't know the details of that.)

Anyway, as a project we need to be able to merge a simple practical fix as in this PR without going on a meandering path of ever-widening scope.

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Feb 15, 2024

Marking as blocker - this needs to be resolved before the release.

@kwankyu
Copy link
Collaborator

kwankyu commented Feb 15, 2024

In spite of your long and bloated discussion, I want to suggest another solution.

There is nothing wrong that required_version() errors out due to a missing file in the situation where sagemath-repl is not installed. Hence I suggest

        from sage.env import SAGE_SHARE, THREEJS_DIR

        threejs_search_path = THREEJS_DIR or (
            os.path.join(SAGE_SHARE, "jupyter", "nbextensions", "threejs-sage"),
            os.path.join(SAGE_SHARE, "sagemath", "threejs-sage"),
            os.path.join(SAGE_SHARE, "sage", "threejs"),
            os.path.join(SAGE_SHARE, "threejs-sage")
            )

        try:
            version = self.required_version()
            filename = os.path.join(version, "three.min.js")
        except FileNotFoundError:
            filename = 'unknown'

        StaticFile.__init__(
            self, name="threejs",
            filename=filename,
            spkg="threejs",
            type="standard",
            search_path=threejs_search_path,
            description="JavaScript library to display 3D graphics")  

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Feb 15, 2024

Thanks, I like this solution.

@kwankyu
Copy link
Collaborator

kwankyu commented Feb 15, 2024

With the fix, the test for sagemath-environment passes.

Please add some comment to the try statement.

Copy link
Collaborator

@kwankyu kwankyu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. LGTM.

@tornaria
Copy link
Contributor

Same dog with a different collar.

The problem I raised is that Threejs().is_present() will incorrectly return False. Still unsolved afaict.

For example, this breaks sage.repl.ipython_kernel.install.use_local_threejs().

The simple solution is to add src/sage/ext_data/threejs/threejs-version.txt to sagemath-environment.

By design, the threejs feature depends on this file to do its job. Not shipping the version information together with the feature is a mistake and the FileNotFoundError is the warning. We should not silence the messenger but fix the underlying issue.

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Feb 15, 2024

By design, the threejs feature depends on this file to do its job. Not shipping the version information together with the feature is a mistake

No, you're mistaken about the design of sage.features:

  • It's part of its design that all Feature classes can be loaded and instantiated without error.
  • It is not part of its design to have self-contained definitions of all feature tests. It is allowed to use delegation.

And the latter is what we're doing here. We are delegating the definition of what version is needed to the module that needs it.

@tornaria
Copy link
Contributor

By design, the threejs feature depends on this file to do its job. Not shipping the version information together with the feature is a mistake

No, you're mistaken about the design of sage.features:

Source: I wrote the "threejs feature", and its documentation reads

A :class:`~sage.features.Feature` which describes the presence of
threejs-sage in a few standard locations.
* It's part of its design that all `Feature` classes can be loaded and instantiated without error.

Reasonable. It is a bug and has to be fixed.

* It is **not** part of its design to have self-contained definitions of all feature tests. It is allowed to use **delegation**.

Not reasonable. We should be very careful to ship features that give different answers depending on which combination of packages is installed.

And the latter is what we're doing here. We are delegating the definition of what version is needed to the module that needs it.

You are still missing the fact that sage.repl needs this feature but the version is not shipped with sage.repl either.

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Feb 15, 2024

  • It is not part of its design to have self-contained definitions of all feature tests. It is allowed to use delegation.

Not reasonable.

I would generally suggest more restraint with making declarations of this type.

We should be very careful to ship features that give different answers depending on which combination of packages is installed.

Saying that sage.features needs to be a self-contained module and that delegation is somehow a violation of principles of modularity -- sorry, this completely misunderstands the purpose of sage.features (and of the distribution sagemath-environment that ships it).

sage.features serves an integration concern. It is the designated place where we orchestrate the interface between the system environment, the providers of features, and the client code. It is exactly the point of sage.features to determine at the runtime (= when the specific combination of packages is present) what features are present.

You are still missing the fact that sage.repl needs this feature but the version is not shipped with sage.repl either.

It does not have to be shipped with sage.repl because it makes use of sage.features for the very purpose of feature discovery.

@kwankyu
Copy link
Collaborator

kwankyu commented Feb 16, 2024

Let me ask some basic questions.

What is the use of src/sage/ext_data/threejs/threejs-version.txt? Where is it used? Only here for feature test?

I find it strange that a feature test needs version information. I guess that no other feature test needs that. Can we do the threejs feature test without the version informaion?

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Feb 16, 2024

I find it strange that a feature test needs version information.

See #37178 (comment) above and #30123, which has all the links. In short, our venv contains a frontend (jupyter notebook), which is able to talk to multiple kernels installed in separate venvs.

@tornaria
Copy link
Contributor

Let me ask some basic questions.

What is the use of src/sage/ext_data/threejs/threejs-version.txt? Where is it used? Only here for feature test?

I find it strange that a feature test needs version information. I guess that no other feature test needs that. Can we do the threejs feature test without the version informaion?

The package threejs-sage contains the following:

$ find threejs-sage/
threejs-sage/
threejs-sage/r122
threejs-sage/r122/three.min.js
threejs-sage/version
$ cat threejs-sage/version 
r122

Where the current version of the package is r122.

The file sage/ext_data/threejs/threejs-version.txt is a configuration file: it contains the required version r122.

Shipping sage/feature/threejs.py without the corresponding sage/ext_data/threejs/threejs-version.txt is a bug. Making it silent does not fix the bug, it only hides the bug.

@kwankyu
Copy link
Collaborator

kwankyu commented Feb 17, 2024

Shipping sage/feature/threejs.py without the corresponding sage/ext_data/threejs/threejs-version.txt is a bug.

sage/feature/threejs.py is a tool to test for a feature, and threejs-version.txt is part of the feature that we use the tool to test for. It is illogical that the tool contains the file.

Perhaps the tool can test presence of threejs-version.txt itself to test the feature. Or it first and then three.min.js.

@tornaria
Copy link
Contributor

Shipping sage/feature/threejs.py without the corresponding sage/ext_data/threejs/threejs-version.txt is a bug.

sage/feature/threejs.py is a tool to test for a feature, and threejs-version.txt is part of the feature that we use the tool to test for. It is illogical that the tool contains the file.

No, the feature is

A :class:`~sage.features.Feature` which describes the presence of
threejs-sage in a few standard locations.

This feature is meant to inform whether the package threejs-sage is installed (in the system, in sage-the-distro, etc). Since sagemath is strict on the version required, we test for the exact version. There's no way to be correct about this test without knowing what is the required version. The version file is not part of the feature, is a support file for the feature.

Perhaps the tool can test presence of threejs-version.txt itself to test the feature. Or it first and then three.min.js.

Here's a trivial way to solve this:

--- a/pkgs/sagemath-environment/MANIFEST.in
+++ b/pkgs/sagemath-environment/MANIFEST.in
@@ -6,6 +6,7 @@ include sage/misc/package.py
 include sage/misc/package_dir.py
 include sage/misc/temporary_file.py
 include sage/misc/viewer.py
+include sage/ext_data/ext_data/threejs/threejs-version.txt
 graft sage/features
 
 include VERSION.txt

An alternative would be for the feature to test the presence of threejs-sage regardless of version. This is how it's done for everything else, e.g. singular feature tests for the presence of a Singular command in PATH (or SINGULAR_BIN), even if the version of singular found might not be the correct one.

@kwankyu
Copy link
Collaborator

kwankyu commented Feb 17, 2024

--- a/pkgs/sagemath-environment/MANIFEST.in
+++ b/pkgs/sagemath-environment/MANIFEST.in
@@ -6,6 +6,7 @@ include sage/misc/package.py
 include sage/misc/package_dir.py
 include sage/misc/temporary_file.py
 include sage/misc/viewer.py
+include sage/ext_data/ext_data/threejs/threejs-version.txt
 graft sage/features
 
 include VERSION.txt

threejs-version.txt is installed by spkg three. It is not a file in the sage library. As far as I know, a distribution package consists of selections of files of the sage lib.

An alternative would be for the feature to test the presence of threejs-sage regardless of version. This is how it's done for everything else, e.g. singular feature tests for the presence of a Singular command in PATH (or SINGULAR_BIN), even if the version of singular found might not be the correct one.

Yes. I prefer this solution.

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Feb 17, 2024

There's no way to be correct about this test without knowing what is the required version.

@tornaria That's correct, but this does not imply at all that sage.features (sagemath-environment) needs to define the version itself. It uses delegation as already explained in #37178 (comment)

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Feb 17, 2024

I'm setting it back to "needs work".

Based on the discussion, it is clear that I should improve the documentation of sage.features (and sagemath-environment) so that it explains its design principles and its role in modularization.

tornaria added a commit to tornaria/sage that referenced this pull request Feb 18, 2024
This makes the feature complete when only sagemath_environment is
installed.

Fixes: sagemath#37178
@tornaria
Copy link
Contributor

--- a/pkgs/sagemath-environment/MANIFEST.in
+++ b/pkgs/sagemath-environment/MANIFEST.in
@@ -6,6 +6,7 @@ include sage/misc/package.py
 include sage/misc/package_dir.py
 include sage/misc/temporary_file.py
 include sage/misc/viewer.py
+include sage/ext_data/ext_data/threejs/threejs-version.txt
 graft sage/features
 
 include VERSION.txt

threejs-version.txt is installed by spkg three. It is not a file in the sage library.

It's a bit confusing: the spkg includes a file named version, installed in SAGE_LOCAL/share/threejs-sage/ which contains the version as a string. The sage library contains a file named threejs-version.txt which is installed in .../sage/ext_data/threejs/.

As far as I know, a distribution package consists of selections of files of the sage lib.

Yes, sure.

An alternative would be for the feature to test the presence of threejs-sage regardless of version. This is how it's done for everything else, e.g. singular feature tests for the presence of a Singular command in PATH (or SINGULAR_BIN), even if the version of singular found might not be the correct one.

Yes. I prefer this solution.

Me too.

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Feb 18, 2024

I would also strongly prefer "1 version". But for this I would strongly suggest to look into using:

... and abandon our custom solution. I don't have time to work on that at the moment.

@tobiasdiez
Copy link
Contributor

It's okay to use delegation to discover if a feature is present, but what the feature is should be defined by the feature class itself (and hence by the distribution shipping the feature class).

This becomes more apparent once you think about this on a more global level: for example, if another class (shipped in yet another distribution or perhaps in a user module) wants to check if the correct version of threejs is installed, then it should only depend on sage-environment. What if that other class needs a different version of threejs?

So the solution of #37380 seems to make the most sense to me.

As an alternative, it would make sense if features have a version constructor argument to pass the version needed. Then the caller can decide what version is appropriate. Would also help to properly annotate doctests that are specific to a certain version of a dependency (there are a few tests of this sort, usually annoted as 'random' or 'not tested').

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Feb 18, 2024

once you think about this on a more global level

That's right, that's the correct level on which to think about it.

But your conclusion is not correct. I'll elaborate when I get back to it, as I said in #37380

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Feb 21, 2024

would also strongly prefer "1 version". But for this I would strongly suggest to look into using:

... and abandon our custom solution

Another option I just came across: https://github.com/Mathics3/mathics-threejs-backend
(I don't have time to check what it does)

@vbraun
Copy link
Member

vbraun commented Feb 25, 2024

Fugly but probably a slight improvement, either way imho rather low priority. I propose to merge so you all can focus your energy on something more relevant

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Feb 25, 2024

Thanks. (But no, it's high priority, as marked.)

vbraun pushed a commit to vbraun/sage that referenced this pull request Feb 25, 2024
sagemathgh-37178: `sage.features.threejs`: Fix modularization regression after sagemath#37024
    
<!-- ^^^^^
Please provide a concise, informative and self-explanatory title.
Don't put issue numbers in there, do this in the PR body below.
For example, instead of "Fixes sagemath#1234" use "Introduce new method to
calculate 1+1"
-->
<!-- Describe your changes here in detail -->
`sage.features` is shipped by **sagemath-environment**, but the version
file that the Feature introduced in sagemath#37024 uses is shipped by
**sagemath-repl**.

This breaks doctesting in a modularized environment. As seen in
ipython/ipython#14317 (https://github.com/ipytho
n/ipython/actions/runs/7731330166/job/21078723213?pr=14317#step:9:136)


<!-- Why is this change required? What problem does it solve? -->
<!-- If this PR resolves an open issue, please link to it here. For
example "Fixes sagemath#12345". -->
<!-- If your change requires a documentation PR, please link it
appropriately. -->

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->
<!-- If your change requires a documentation PR, please link it
appropriately -->
<!-- If you're unsure about any of these, don't hesitate to ask. We're
here to help! -->
<!-- Feel free to remove irrelevant items. -->

- [x] The title is concise, informative, and self-explanatory.
- [x] The description explains in detail what this PR is about.
- [ ] I have linked a relevant issue or discussion.
- [ ] I have created tests covering the changes.
- [ ] I have updated the documentation accordingly.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on
- sagemath#12345: short description why this is a dependency
- sagemath#34567: ...
-->

<!-- If you're unsure about any of these, don't hesitate to ask. We're
here to help! -->
    
URL: sagemath#37178
Reported by: Matthias Köppe
Reviewer(s): Gonzalo Tornaría, Kwankyu Lee, Matthias Köppe
vbraun pushed a commit to vbraun/sage that referenced this pull request Feb 26, 2024
sagemathgh-37178: `sage.features.threejs`: Fix modularization regression after sagemath#37024
    
<!-- ^^^^^
Please provide a concise, informative and self-explanatory title.
Don't put issue numbers in there, do this in the PR body below.
For example, instead of "Fixes sagemath#1234" use "Introduce new method to
calculate 1+1"
-->
<!-- Describe your changes here in detail -->
`sage.features` is shipped by **sagemath-environment**, but the version
file that the Feature introduced in sagemath#37024 uses is shipped by
**sagemath-repl**.

This breaks doctesting in a modularized environment. As seen in
ipython/ipython#14317 (https://github.com/ipytho
n/ipython/actions/runs/7731330166/job/21078723213?pr=14317#step:9:136)


<!-- Why is this change required? What problem does it solve? -->
<!-- If this PR resolves an open issue, please link to it here. For
example "Fixes sagemath#12345". -->
<!-- If your change requires a documentation PR, please link it
appropriately. -->

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->
<!-- If your change requires a documentation PR, please link it
appropriately -->
<!-- If you're unsure about any of these, don't hesitate to ask. We're
here to help! -->
<!-- Feel free to remove irrelevant items. -->

- [x] The title is concise, informative, and self-explanatory.
- [x] The description explains in detail what this PR is about.
- [ ] I have linked a relevant issue or discussion.
- [ ] I have created tests covering the changes.
- [ ] I have updated the documentation accordingly.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on
- sagemath#12345: short description why this is a dependency
- sagemath#34567: ...
-->

<!-- If you're unsure about any of these, don't hesitate to ask. We're
here to help! -->
    
URL: sagemath#37178
Reported by: Matthias Köppe
Reviewer(s): Gonzalo Tornaría, Kwankyu Lee, Matthias Köppe
Copy link

Documentation preview for this PR (built with commit a2ce28c; changes) is ready! 🎉

@vbraun vbraun merged commit 14a228f into sagemath:develop Feb 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants